C 动态分配和程序
我不明白为什么我的代码的第一个版本可以工作,而第二个版本不行 第一版:C 动态分配和程序,c,C,我不明白为什么我的代码的第一个版本可以工作,而第二个版本不行 第一版: #include <stdio.h> #include <stdlib.h> void procedure(int *t){ t = (int*)realloc(t, 4*sizeof(int)); t[3] = 4; } int main() { int *var; var = (int*)malloc(sizeof(int)); procedure
#include <stdio.h>
#include <stdlib.h>
void procedure(int *t){
t = (int*)realloc(t, 4*sizeof(int));
t[3] = 4;
}
int main()
{
int *var;
var = (int*)malloc(sizeof(int));
procedure(var);
printf("%d\n\n", var[3]);
}
#包括
#包括
无效程序(int*t){
t=(int*)realloc(t,4*sizeof(int));
t[3]=4;
}
int main()
{
int*var;
var=(int*)malloc(sizeof(int));
程序(var);
printf(“%d\n\n”,var[3]);
}
第二版:
#include <stdio.h>
#include <stdlib.h>
void procedure(int *t){
t = (int*)malloc(4*sizeof(int));
t[3] = 4;
}
int main()
{
int *var = NULL;
procedure(var);
printf("%d\n\n", var[3]);
}
#包括
#包括
无效程序(int*t){
t=(int*)malloc(4*sizeof(int));
t[3]=4;
}
int main()
{
int*var=NULL;
程序(var);
printf(“%d\n\n”,var[3]);
}
在第二个版本中,var在过程执行后仍然是空指针。为什么? 如果您想阅读C标准中的功能描述
realloc
,您就会知道
返回4
realloc函数返回指向新对象的指针
(可能与指向旧对象的指针具有相同的值),或
如果无法分配新对象,则为空指针
因此,在第一种情况下,指针的值没有改变。尽管依赖于此会导致未定义的行为
在第二种情况下,当使用标准函数malloc
时,将分配具有不同地址的新区段。因此,原始指针不会指向内存的新范围,因为它是通过值传递给函数的
因此,在这两种情况下,原始指针都没有改变。不同之处在于,在第一种情况下,系统可以在保持其原始地址不变的情况下扩大内存范围,而在第二种情况下,系统使用不同的地址分配新的范围。您应该记住,C中的所有内容都是通过值传递的,甚至指针。让我们从第二个例子开始
将main中的var
设置为NULL。然后将其中的地址(NULL)复制到过程中的变量t
。您进入malloc
内存,并将该地址分配给t
。但是t
只是var
的一个副本,对t
的任何更改都不会反映在var
中。在过程
之外,指针保留空地址,使用var[3]
调用printf
是未定义的行为
第二个病例的症状相同,但有扭转realloc
不必返回其他地址。它是内存分配器感知的,所以如果它能够“扩展”所指向的内存块,它就会。这就是你所看到的。调用realloc
扩展内存并返回给定的相同地址。因此,完全巧合的是,t
和var
最终仍然指向同一个位置
这就是为什么使用var[3]
可以看到对t[3]
的修改。这不是一个你可以依赖的行为。让我们在这里一步一步来
int*t
表示“t的地址”,意思是它只是一个数字
- 将任何数字传递给函数意味着您正在将该数据复制到该函数中(而不是链接它)
- 这意味着该数字可以在函数内部更改,但不能在函数外部更改(因为它是一个副本)
- 即使
t
是一个指针,该指针仍然是一个数字。。。设置为其他值(即t=(int*)malloc(4*sizeof(int));
)并不意味着var
的值已更改。(因为同样,t
是var
的副本)
在代码的第二个版本中,您只需将地址var
指向。在过程(…)
中,本质上您已经声明了一个int指针,并且在第一行(malloc行)上,您正在为该指针赋值<代码>var
不会使用此值更新,因为var是一个完全独立的实体
从本质上讲,您最好执行以下操作:
int *var = NULL;
int *t = malloc(4*sizeof(int));
t[3]=4;
printf("%d\n\n", var[3]);
var
从未重新分配给任何对象,因此var将始终为null
但这是可以纠正的,就像这样:
#include <stdio.h>
#include <stdlib.h>
void procedure(int **t){
*t = malloc(4*sizeof(int));
(*t)[3] = 4;
}
int main()
{
int *var = NULL;
procedure(&var);
printf("%d\n\n", var[3]);
}
#包括
#包括
无效程序(int**t){
*t=malloc(4*sizeof(int));
(*t)[3]=4;
}
int main()
{
int*var=NULL;
程序(var);
printf(“%d\n\n”,var[3]);
}
您可以在以下位置查看此工作:
编辑:另外,值得注意的是,您应该在第一个版本中执行相同的操作,因为
realloc(…)
可能会返回与var
不同的地址,这可能会导致内存泄漏。对于@EdHeal可能的重复项,realloc
或malloc
不需要强制转换为什么?练习的目的是使用malloc@DocMogrog-尽管如此,您仍然不需要对两个函数的结果进行强制转换。@EdHeal,啊,谢谢您指出这一点。我复制了OP的代码,忘了更改:P