realloc 似乎没有重新分配内存

realloc seems to not be reallocating memory

我需要动态地将一个字符附加到一个字符串,所以我使用 realloc() 来根据需要添加更多内存。

我是 C 的新手(来自 Python),所以我阅读了很多书,这是我能做的最好的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void append_to(char *array, char value) {
    size_t buffer = (strlen(array) * sizeof(char)) + sizeof(char);
    char *new_array = realloc(array, buffer);
    if (new_array == NULL) {
        printf("CRITICAL ERROR\n");
        exit(-1);
    }
    array = new_array;
    int position = strlen(array);
    array[position] = value;
}

int main() {
    char *list = malloc(sizeof(char));
    for (int i = 1; i < 26; i++){
        append_to(list, 'a');
        printf("%d -> %s\n", i, list);
    }
}

这只是一个展示问题的例子。代码运行完美,直到第 24 次迭代,见下文:

1 -> a
2 -> aa
[...] //omitted
23 -> aaaaaaaaaaaaaaaaaaaaaaa
24 -> aaaaaaaaaaaaaaaaaaaaaaaa
25 -> 

我错过了什么?

首先,您忘记在 c 字符串的末尾添加另一个 NUL 字符。

其次,realloc可能会改变数据的内存位置,但是你传递的是list as值,所以在数据重定位的情况下,重定位是不可见的。

应该是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void append_to(char **array, char value) { // pass pointer's address
    size_t buffer = (strlen(*array) * sizeof(char)) + sizeof(char) + sizeof(char); // one more to tackle the end of the string
    char *new_array = realloc(*array, buffer);
    if (new_array == NULL) {
        printf("CRITICAL ERROR\n");
        exit(-1);
    }
    *array = new_array;
    int position = strlen(*array);
    (*array)[position] = value;
    (*array)[position+1] = 0; // end of string
}

int main() {
    char *list = malloc(sizeof(char));
    list[0] = 0; // end of string
    for (int i = 1; i < 26; i++){
        append_to(&list, 'a'); // pass address of array so that it can be changed by the call
        printf("%d -> %s\n", i, list);
    }
    free(list); // always explicitly free unused resources
}

您没有收到 array 作为双指针,因此当 realloc 必须移动分配时,您无法重新分配调用者的指针。

要修复,

// Receive double pointer
void append_to(char **array, char value) {
    // Add dereferencing as needed
    size_t buffer = (strlen(*array) + 2) * sizeof(char);
    char *new_array = realloc(*array, buffer);
    if (new_array == NULL) {
        printf("CRITICAL ERROR\n");
        exit(-1);
    }
    *array = new_array;
    int position = strlen(*array);
    array[0][position] = value;
    array[0][position+1] = '[=10=]'; // Explicitly NUL terminate, don't assume new memory is zeroed
}

int main() {
    char *list = malloc(sizeof(char));
    for (int i = 1; i < 26; i++){
        append_to(&list, 'a');  // Pass address of list
        printf("%d -> %s\n", i, list);
    }
}