web-dev-qa-db-ja.com

Cの構造体の配列に適切にmallocする方法

2組のchar*(または文字列)はstrtokを使用し、これら2つの文字セットは関連しているため、(address : command\n)構造体を使用することにしました。

struct line* array = (struct line*)malloc(sizeof(file) * sizeof(struct line*));

この関数のmallocing行は、セグメンテーションエラーを引き起こし、malloc spaceの適切な方法を教えてくれるかどうか疑問に思っていました。コンテキストのために、ここに私のコードの残りがあります:

struct line
{
    char* addr;
    char* inst;
};
while loop{
    x = strtok(line,": ");
    y = strtok(NULL,"\n");
    strcpy(array[i].addr,x); //assume that x and y are always 3characters
    strcpy(array[i].inst,++y);
    i++;
}
12
o0tomato0o

割り当ては、すべてのタイプで同じように機能します。 line構造体の配列を割り当てる必要がある場合は、次のようにします。

_struct line* array = malloc(number_of_elements * sizeof(struct line));
_

コードでは、line構造体ではなく、lineポインターに適切なサイズの配列を割り当てていました。また、malloc()の戻り値をキャストする理由がないことに注意してください。

使用する方が良いスタイルであることに注意してください:

_sizeof(*array)
_

の代わりに:

_sizeof(struct line)
_

これは、arrayのタイプを変更した場合でも、割り当てが意図したとおりに機能するためです。この場合、これはほとんどありませんが、慣れる価値のある一般的なことです。

また、構造体をstructingすることで、Word typedefを何度も繰り返さなくても済むことに注意してください。

_typedef struct line
{
    char* addr;
    char* inst;
} line;
_

その後、次の操作を実行できます。

_line* array = malloc(number_of_elements * sizeof(*array));
_

もちろん、_array.addr_および_array.inst_にもメモリを割り当てることを忘れないでください。

20
Nikos C.

説明した内容については、構造体にメモリを割り当てる必要はありませんrather、メンバーにメモリを割り当てる必要がありますchar *addr;、およびchar *inst;。その構造の単一のコピーが必要な場合は、コードの最初のセクションで初期化および値の割り当て方法を示します。配列が必要な場合、2番目のコード例は違いを示しています。

これは、single struct line:のメンバーにメモリを割り当てる方法を示しています

typedef struct
{
    char* addr;
    char* inst;
}LINE;

LINE line;  

int main(void)
{   

    strcpy(line.addr, "anystring"); //will fail
    line.addr = malloc(80);
    line.inst = malloc(80);
    strcpy(line.addr, "someString");//success;
    strcpy(line.inst, "someOtherString");//success;

}

struct lineの配列の場合...

typedef struct
{
    char* addr;
    char* inst;
}LINE;  //same struct definition

LINE line[10]; //but create an array of line here.

int main(void)
{   
    int i;

    for(i=0;i<10;i++)
    {
      line[i].addr = malloc(80);
      line[i].inst = malloc(80);
    }

    for(i=0;i<10;i++)
    {
        strcpy(line[i].addr, "someString");
        strcpy(line[i].inst, "someOtherString");
    }
    //when done, free memory
    for(i=0;i<10;i++)
    {
        free(line[i].addr);
        free(line[i].inst);
    }      


}
4
ryyker