在调整动态结构数组时,是否需要在结构中复制动态内存?

时间:2016-08-27 22:03:52

标签: c malloc

我有一个动态数组,其中每个元素都是一个结构,其中包含一个动态分配的字符数组。

当我调整数组大小时,我创建了一个比旧数组大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数据复制到新数组中?

1 个答案:

答案 0 :(得分: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实现相同的目标,但您必须更加小心。