【问题标题】:Unexpected behavior of string reallocation字符串重新分配的意外行为
【发布时间】:2025-12-13 16:05:01
【问题描述】:

我遇到了一个奇怪的使用字符串函数分配内存的行为。

注意:现在我被告知忽略分配操作的失败。

我的代码是:

void string_reallocation(char *result, int result_length) {
    char *temp_result = malloc((strlen(result) + 1) * sizeof(char));

    strcpy(temp_result, result);

    realloc(result, (result_length + 1) * sizeof(char));

    strcpy(result, temp_result);

    free(temp_result);
}

在 while 循环中通过迭代调用此函数:

    while (current_node != NULL) {
        current_value_to_string = current_node->toStringFunc(current_node->value);
        current_value_length = (int) strlen(current_value_to_string);
        current_length += current_value_length + arrow_length;

        string_reallocation(result, current_length);

        strcat(result, current_value_to_string);
        strcat(result, arrow);

        current_node = current_node->next;
    }

current_node 的类型如下:

typedef struct t_node {
    Element value;
    struct t_node *next;
    elementDestroy destroyFunc;
    elementCopy copyFunc;
    elementToString toStringFunc;
} *Node;

问题是,出于某种原因,特别是在第三次迭代中,free(temp_result); 因分段错误而失败。

我不认为 while 循环与分段错误有任何关系,但我把它放在这里以防万一。

【问题讨论】:

  • 试试result = realloc(result, (result_length + 1) * sizeof(char));。 GTG
  • @chux-ReinstateMonica 现在在第三次迭代后result 的值是乱码。
  • 另外,char *result 必须是 char **result,因为 char * 的地址只会在堆栈上被覆盖,并且函数结束后你会丢失 realloc 返回的新地址

标签: c pointers malloc free realloc


【解决方案1】:

这是一个双相解决方案,因为您必须通过检查其原型来了解如何使用realloc()。让我们先这样做。

改变这个:

realloc(result, (result_length + 1) * sizeof(char));

到这里:

result = realloc(result, (result_length + 1) * sizeof(char));

reference开始,我们得到了这个方法的原型:

返回值:指向重新分配的内存块的指针,可能是 与 ptr 相同或新位置。


现在,考虑一下变量(指针)的范围。正如@whozCraig 评论的那样,result =(在更正后的realloc() 中)为自动变量赋值。在调用方传递的原始结果没有改变,现在悬空。这必须使用输入/输出参数或函数返回结果来处理。

所以你可以做的就是简单地返回那个指针,通过改变这个:

void string_reallocation(char *result, int result_length) {

到那个:

char* string_reallocation(char *result, int result_length) {
  // ...
  return result;
}

然后把这个函数的调用改成这个:

result = string_reallocation(result, current_length);

【讨论】:

  • @WhozCraig 我将您的评论注入到我的回答中,希望没关系。请看一下,如果有任何问题,请告诉我。谢谢!
最近更新 更多