通过动态分配创建数组后,在C中通过realloc改变内存大小时出现问题

Posted

技术标签:

【中文标题】通过动态分配创建数组后,在C中通过realloc改变内存大小时出现问题【英文标题】:After creating an array through dynamic allocation, a problem occurs when changing the memory size through realloc in C 【发布时间】:2021-01-29 02:34:42 【问题描述】:

我正在练习 C 语言。

我想使用动态分配,只使用我输入的字符串的大小作为内存,并检查输入的字符串是否正确保存。

所以,我使用 malloc 和 realloc 函数编写了以下代码。

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


void str_copy(char* str_array_f) 

    void* tmp;
    char buf;
    unsigned char arr_size = 1; 
    unsigned char arr_cur = 0;

    while ((buf = getchar())) 
        if (buf == '\n') 
            break;
        
        str_array_f[arr_cur++] = (char)buf;

        tmp = realloc(str_array_f, ((arr_size++) * sizeof(char)) + sizeof(char));
        if (tmp != 0) 
            str_array_f = tmp;
        
        else 
            printf("memory leak error occur! \n");
            break;
        
    
    str_array_f[arr_size - 1] = 0x00; 
    



void main() 

    int contiune = 1;

    while (contiune) 
        char* str_array = malloc(sizeof(char) + sizeof(char));

        printf("Please type something : ");
        str_copy(str_array);

        printf("'str_array' have this : %s \n", str_array);
        printf("-------------------------------------------------\n");
        if (str_array[0] == '1') 
            contiune = 0;
        
        free(str_array);
    


而且,由于性能, 出现以下问题。

    有时从间歇打印值的第 5 个字符开始出现奇怪的值 (要重现这个问题,建议去掉while循环,反复尝试)

    在使用while循环重复接收值的情况下,重复4次后出错。

    如果tmp分配的内存是一个void类型的指针,在第22行之后被释放(例如'free(tmp);'),执行时没有输出,立即出错。

对于上述3个问题,我不确定是什么原因以及如何解决。

如果有解决办法,请告诉我。

而且,如果我的代码在效率或各方面有不好的编码方法,请告诉我。

*编程执行环境:Visual Studio 2019

【问题讨论】:

你找到这个问题的答案了吗? 【参考方案1】:

为了解释你做错了什么,我将在这里使用一个最小的例子

void change_x(int x) 
    x = 2;


int main() 
    int x = 1;
    change_x(x);
    printf("%i\n", x); // it'll print 1 not 2
    return 0;

这里的整数 x 在函数被调用时被复制,改变它并不会真正改变 main 中的 x。同样,您在代码中所做的 str_array_f = tmp; 它实际上不会更改 str_array 而是复制的值。并且您正在尝试释放之前重新分配的指针。

上面例子的解决方法是不传递值 x 而是传递 x 的地址(在其他语言中相当于通过引用传递)

void change_x(int* x) 
    *x = 2;


int main() 
    int x = 1;
    change_x(&x);
    printf("%i\n", x); // it'll print 1 not 2
    return 0;

为了你的代码

void str_copy(char** str_array_f) ... // change the parameter
*str_array_f = tmp; // de reference and use it.

str_copy(&str_array); // call with it's address

还有一件事,不要更频繁地重新分配它不是有效的。相反,只需分配具有最小大小的“数组”类型,当它被填满时,重新分配它的 2 倍大小(或者如果你愿意,可以 1.5)

【讨论】:

以防万一这不起作用,我认为您的内存管理有问题。我已经通过 Valgrind memcheck 运行了该程序,并且我得到了无效读取和无效免费等内容。它也会显示详细信息,以防您想查看

以上是关于通过动态分配创建数组后,在C中通过realloc改变内存大小时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

c语言中如何定义动态数组

C 编程 - realloc 应该多久使用一次?

malloc,realloc,与calloc

c中可以定义变长数组吗

在 Swig 中通过 ref 返回动态数组

内存动态分配之realloc(),malloc(),calloc()与new运算符