23

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

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

このmalloc関数の行間スペースは、セグメンテーション違反を引き起こします。適切なmallocスペースを確保する方法を教えていただけないでしょうか。コンテキストのために、ここに私のコードの残りの部分があります:

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++;
}
4

2 に答える 2

29

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

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

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

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

sizeof(*array)

それ以外の:

sizeof(struct line)

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

また、構造体を ing することで、単語structを何度も繰り返す必要がなくなることにも注意してください。typedef

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

その後、次のことができます。

line* array = malloc(number_of_elements * sizeof(*array));

もちろん、array.addrとにもメモリを割り当てることを忘れないでくださいarray.inst

于 2013-10-27T01:40:05.413 に答える
8

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

これは、単一の構造体行のメンバーにメモリを割り当てる方法を示しています。

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;

}

構造体行の配列の場合...

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);
    }      


}

アドレス コメントに追加
@Adam Liss からのこの回答の下にあるコメントに対処すると、次のコードはstrdup()を使用した次の改善を示しています。1 ) 必要なメモリのみを使用します。2) メモリの作成とコピー操作を 1 つのステップで実行するため、次のブロック:

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");
}

なる:

for(i=0;i<10;i++)
{
  line[i].addr = strdup("someString");
  line[i].inst = strdup("someOtherString");
}

もう 1 つ注意:主な概念への焦点が混乱するのを避けるため、上記の例にはエラー処理が含まれていません: ただし、完全を期すために、 と の両方malloc() strdup()失敗する可能性があるため、これら 2 つの関数のそれぞれの実際の使用法には、使用する前にテストを含める必要があります。 、例:

それよりも

  line[i].addr = strdup("someString");
  line[i].inst = strdup("someOtherString");

コードには次を含める必要があります

  line[i].addr = strdup("someString");
  if(!line[i].addr)
  {
      //error handling code here
  }
  line[i].inst = strdup("someOtherString");
  if(!line[i].inst)
  {
      //error handling code here
  }
于 2013-10-27T01:55:44.933 に答える