如何在C语言函数中使用realloc

39

基于我在这里学到的内容: 在C语言中通过函数操作动态数组.

void test(int data[])
{
    data[0] = 1;    
}    

int main(void)
{    
    int *data = malloc(4 * sizeof *data);

    test(data);

    return 0;
}

这个可以正常工作。但是,我也尝试在一个函数中使用 realloc

void increase(int data[])
{
    data = realloc(data, 5 * sizeof *data);    
}

这样做是符合要求的,但程序在运行时崩溃了。

问题

在函数中应该如何使用realloc?

我知道应该将realloc的结果赋值给一个变量并先检查它是否为NULL。这只是一个简化的示例。


17
我不敢相信你没有对malloc()的返回值进行强制转换并且你还正确地使用了sizeof()操作符……太棒了!+1。 - user529758
欢迎。信不信由你,每次我遇到一个标记为“c”的问题时,我都必须准备好应对像char *p = (char *)malloc(len * sizeof(char);这样的混乱代码,至少有3个地方是错误的(练习:找出哪里错了)。 - user529758
8
冒昧问一句:1. 在使用 malloc 函数前写的 cast 是不必要的。2. sizeof *p 等价于 sizeof(char),但在更改类型时更有用。3. 缺少一个右括号“)”? - Legendre
4
哦,原来是4!是的,我确实漏掉了右括号(第0个错误)。第一个:勾选,第二个:由于sizeof(char)始终为1,它只是杂乱无章并降低可读性,第三个:如果您使用sizeof(),您应该真正使用 sizeof(*variable)而不是sizeof(type),因为后者在更改*p的类型时出问题。 - user529758
啊,我对编程还比较新,没意识到sizeof(char)的标准值是1。今天学到了一些新东西,感谢这个有趣的练习!+1 - Legendre
@lundin,我打开了这个问题,因为它也涉及到realloc... - Antti Haapala -- Слава Україні
3个回答

38

您想要修改一个 int* 的值(即您的数组),因此需要将指向它的指针传递给您的 increase 函数:

void increase(int** data)
{
    *data = realloc(*data, 5 * sizeof int);
}

调用代码将类似于:

int *data = malloc(4 * sizeof *data);
/* do stuff with data */
increase(&data);
/* more stuff */
free(data);

3
当心内存泄漏!如 https://dev59.com/-mYr5IYBdhLWcg3wW45t#44071325 中所提到的,您需要使用一个临时指针来检查 realloc 返回值。 - luca

8

请记住指针和数组之间的区别。
一个数组是位于堆栈中的一块内存,就是这样。如果你有一个数组:

int arr[100];

那么 arr 是一个内存地址,而 &arr 也是一个内存地址,该内存地址是固定的,不存储在任何位置。因此,您不能说 arr = NULL,因为 arr 不是指向某个变量的变量。它只是一个符号性的地址:数组开始的地址。相反,指针有自己的内存,可以指向内存地址。
只需将 int[] 改为 int* 即可。
另外,变量是按副本传递的,因此需要将 int** 传递给函数。
关于如何使用 realloc,所有教学示例都包括以下步骤:
1. 使用 realloc; 2. 检查是否为 NULL。如果是,则使用 perror 并退出程序; 3. 如果不是 NULL,请使用分配的内存; 4. 当您不再需要它时,请释放内存。
所以这将是一个不错的例子:
int* chuck= (int*) realloc (NULL, 10*sizeof(int)); // Acts like malloc,
              // casting is optional but I'd suggest it for readability
assert(chuck);
for(unsigned int i=0; i<10; i++)
{
    chunk[i]=i*10;
    printf("%d",chunk[i]);
}
free(chunk);

6

这两段代码都存在问题,如果你使用同一个指针进行realloc的发送和接收操作,如果它失败了,你将失去它的指针以便以后释放内存。

你应该像这样做:

{ ... ...

more = realloc(area , size);
if( more == NULL )
    free(area);
else
    area=more;

抱歉,你需要提供需要翻译的具体内容。

4
如果 realloc 失败,你需要在失败时调用 free(area) 来释放内存。但是如果我不想释放它,能否继续使用 area 内存块? - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接