2016-08-27 17 views
1

私は動的配列を持っています。各要素は、とりわけ動的に割り当てられた文字配列を含む構造体です。

アレイのサイズを変更すると、古いアレイより約50%大きい新しいアレイを作成し、古いアレイのデータを新しいアレイにコピーし、古いアレイを削除します。ここで
はコードです:
構造体の動的配列のサイズを変更するときに、構造体に動的メモリをコピーする必要がありますか?

typedef struct Thing 
{ 
    char* str; /* dynamic memory */ 
    int num; 
    int other_data; 
} thing; 

typedef struct ThingStream 
{ 
    thing* things; /* dynamic memory */ 
    int capacity; 
    int size; 
} thing_stream; 

void resize_thing_stream(thing_stream* ts) 
{ 
    int new_capacity; 
    thing* new_things; 
    int i; 

    new_capacity = ts->capacity + ts->capacity/2; 
    new_things = malloc(new_capacity * sizeof(thing)); 

    for(i = 0; i < ts->size; i++) 
    { 
     new_things[i] = ts->things[i]; 
     /* here is where I would copy the str data */ 
    } 

    free(ts->things); 
    ts->things = new_things; 
    ts->capacity = new_capacity; 
} 

は、私はちょうどstrが新しい配列になることを期待することができ、または私は新しい配列にstrデータをコピーする必要がありますか?

+3

は単に 'realloc'を使用します。 – BLUEPIXY

+3

文字列のメモリをコピーする必要はありません。各要素は、割り当てられたメモリへのポインタを保持しているため、再割り当てする必要はありません。だから答えは「はい」です。新しい配列に 'str'があると期待できます。 – ProXicT

+0

ありがとう!ダイナミックメモリを含むダイナミックメモリを解放するとメモリリークが発生する可能性があると思われるその他の質問と回答がありました。 – biscuit

答えて

1

より簡単に始めることができます。バッファにテキストを書き込んだ後、bufのサイズを増やして、それに文字数を増やしたいとします。最も簡単な方法は、reallocを使用することです:

int main() 
{ 
    char *buf; 
    buf = malloc(4); 
    strcpy(buf, "123"); 

    buf = realloc(buf, 7); 
    strcat(buf, "456"); //buf still contains 123 
    puts(buf);//output: 123456 

    free(buf); 
} 

あなたはmallocと同じことを達成することができます。しかし、もう一度mallocを使用するには、古い文字列を別の文字列に保存し、古い割り当てを解放し、より大きなバッファを割り当てて、古い文字列をコピーする必要があります。例:いくつかの構造でこれを入れて

char *buf; 
buf = malloc(4); 
strcpy(buf, "123"); 

char *temp = strdup(buf); //save the old string 
free(buf);     //free the old string 
buf = malloc(7);   //allocate new size 
strcpy(buf, temp);   //copy the old string 
strcat(buf, "456");   //finally the string is ready 
free(temp);     //cleanup temp variable 

puts(buf); 

free(buf); 

typedef struct string_t 
{ 
    char* data; 
    int capacity; 
} string; 

void string_reserve(string *str, int capacity) 
{ 
    str->data = realloc(str->data, capacity);//str->data was initialized to zero 
    str->capacity = capacity; 
} 

int main() 
{ 
    string str; 

    //initialize str: 
    str.data = 0; 
    str.capacity = 0; 

    string_reserve(&str, 4); 
    strcpy(str.data, "123"); 

    string_reserve(&str, 7); 
    strcat(str.data, "456"); 
    puts(str.data); 

    //free memory 
    free(str.data); 

    return 0; 
} 

再びあなたがmallocと同じことを達成することができますが、あなたはもっと注意する必要があります。

関連する問題