4

私は単純な構造を持っています:

typedef struct {
    int width, height;
    unsigned char *pixels;
} image;

どちらが優れた API ですか?

image *imagecreate(int w, int h) {
    image *img = malloc(sizeof(image));
    img->width = w;
    img->height = h;
    img->pixels = calloc(w * h, 3);
    return img;
}

void imagefree(image *img) {
    free(img->pixels);
    free(img);
}

また

image imagecreate(int w, int h) {
    image img;  
    img.width = w;
    img.height = h;
    img.pixels = calloc(w * h, 3);
    return img;
}

void imagefree(image *img) {
    free(img->pixels);
    img->width = img->height = 0;
}

?

実際の動的に割り当てられたデータへのポインターのラッパーにすぎないこのような小さな構造体に対して追加の malloc() を実行するのはやり過ぎのようです。しかし一方で、動的に割り当てられたメモリへのポインターを値型内に隠すのは (私にとっては) 不自然に感じます。解放する必要はないと考えることができます。

4

3 に答える 3

2

あなたはAPIについて話している。したがって、クライアントが正しく使いやすく、間違って使いにくいことが重要です。

オプション#2の小さな改善

たとえば、私が 2 番目の API のユーザーである場合:

image imagecreate(int w, int h);
void imagefree(image *img);

オブジェクトへのポインターではなくオブジェクトを返すため、ポインターが必要なimagefreeため、呼び出す必要があることに気付かないでしょう。ヒープ割り当てオブジェクトの単なるラッパーだと思うかもしれません。したがって、「スタック」オブジェクトには使用しません。imagecreateimagefreeimagefreedelete image

したがって、これはより良いです:

image imagecreate(int w, int h);
void imagefree(image img);

内部imageにヒープ割り当てメンバーがありますが、これらの API でそれを非表示にするのは良いことです。また、一貫した「見た目」があり、より優れており、エラーが発生しにくくなっています。

では、オプション 1 についてはどうでしょうか。

あなたの最初の選択肢についてですが、それはさらに良いですか?それは(個人に)依存します。私としては、オプション#1をお勧めします。

image *imagecreate(int w, int h);
void imagefree(image *img);

なんで?

C++ の RAII のようなデストラクタによるリソースの自動破棄を強制する方法はありませんが、通常、API から返された「ポインター」を見る C プログラマーにはより注意が払われます (私たちはポインターに敏感ですよね? ? ;)。内部で動的に割り当てられているimagecreateか? 他の API を介して割り当てを解除する必要がありますか?

于 2012-04-17T09:39:02.563 に答える
1

違いはstruct、最初のケースでは your が動的に割り当てられ、2 番目のケースでは自動的に割り当てられることです。それは個人的な好み、コーディング基準、および意見の問題です。free2番目の方法は、覚えておくべきことが1つ少ないため、私には安全に思えますが、freeとにかくしなければならないので、それほど重要ではありません。

struct2 番目のケースでは、 が戻り値にコピーされることに注意してください。あなたはその中のポインターをうまく扱っているようですが、そこには潜在的な地雷があります.

于 2012-04-17T08:17:01.500 に答える
1

私は最初に行きます。構造体に記述子「char name [100]」があると仮定すると、2番目は100バイトのスタックスペースを使用し、オペレーティングシステムで処理する必要がありますが、最初のメモリは自分で処理できます(標準の malloc) を使用して、限られたスタック スペースを気にすることなく、好きなようにハンドルをオブジェクトに移動できます。

于 2012-04-17T09:07:07.470 に答える