realloc似乎没有重新分配内存

时间:2018-05-31 05:18:55

标签: c string pointers malloc realloc

我需要动态地将字符串附加到字符串,因此我使用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 -> 

我错过了什么?

2 个答案:

答案 0 :(得分:3)

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

其次,realloc可能会更改数据的内存位置,但是您将list作为值传递,因此在数据重定位的情况下,重定位不可见。

那应该像lokks:

#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
}

答案 1 :(得分:2)

您没有收到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] = '\0'; // 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);
    }
}