c语言realloc函数疑惑
本帖最后由 mxwawaawxm 于 2020-9-20 20:00 编辑之前看视频时,听到函数参数传递时,是值参递。也就是函数内部会新建一个变量存放实参的值
所以在main函数通过malloc函数动态分配内存,赋予了变量arr6个int大小的字节;而后在gen(int *arr)里调用realloc函数扩大内存,把它扩大到8个int
最后,居然外部的arr也跟着扩大了。而且gen函数内部、main函数外部运行的打印结果是一致的{:301_982:}
#include <stdio.h>#include <stdlib.h>
#include <time.h>
void gen(int *arr);
void print_arr(int *arr, int num);
int main(int argc, const char *argv[])
{
srand(time(NULL));
int *arr = (int *)malloc(sizeof(int)*6);
gen(arr);
print_arr(arr, 8);
free(arr);
return 0;
}
void gen(int *arr)
{
int i;
for (i=0;i<6;i++) {
*(arr+i) = rand()%9+1;
}
arr = (int *)realloc(arr, sizeof(int)*8);
*(arr+6) = rand()%9+1;
*(arr+7) = rand()%9+1;
print_arr(arr, 8);
}
void print_arr(int *arr, int num)
{
int i;
printf("%s\n", __FUNCTION__);
for (i=0;i<8;i++) {
printf("%d ", *(arr+i));
}
printf("\n");
}
接着,做了个测试,在gen函数内部通过malloc函数动态分配内存,赋予temp变量2个int大小的字节,并赋值
最后再赋值给arr变量
结果,编译没报错。运行出现随机值
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gen(int *arr);
void print_arr(int *arr, int num);
int main(int argc, const char *argv[])
{
srand(time(NULL));
int *arr = (int *)malloc(sizeof(int)*6);
gen(arr);
print_arr(arr, 8);
free(arr);
return 0;
}
void gen(int *arr)
{
int i;
int *temp = (int *)malloc(sizeof(int)*2);
for (i=0;i<2;i++) {
*(temp+i) = rand()%9+1;
}
for (i=0;i<6;i++) {
*(arr+i) = rand()%9+1;
}
arr = (int *)realloc(arr, sizeof(int)*8);
*(arr+6) = *(temp+0);
*(arr+7) = *(temp+1);
print_arr(arr, 8);
free(temp);
}
void print_arr(int *arr, int num)
{
int i;
printf("%s\n", __FUNCTION__);
for (i=0;i<8;i++) {
printf("%d ", *(arr+i));
}
printf("\n");
}
后面又再做了一次测试,依旧编译通过,但运行出错
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gen(int *arr, int *temp);
void print_arr(int *arr, int num);
int main(int argc, const char *argv[])
{
srand(time(NULL));
int *arr = (int *)malloc(sizeof(int)*6);
int *temp = NULL;
gen(arr, temp);
print_arr(arr, 8);
free(arr);
free(temp);
return 0;
}
void gen(int *arr, int *temp)
{
int i;
temp = (int *)realloc(temp, sizeof(int)*2);
for (i=0;i<2;i++) {
*(temp+i) = rand()%9+1;
}
for (i=0;i<6;i++) {
*(arr+i) = rand()%9+1;
}
arr = (int *)realloc(arr, sizeof(int)*8);
*(arr+6) = *(temp+0);
*(arr+7) = *(temp+1);
print_arr(arr, 8);
}
void print_arr(int *arr, int num)
{
int i;
printf("%s\n", __FUNCTION__);
for (i=0;i<8;i++) {
printf("%d ", *(arr+i));
}
printf("\n");
}
后面两个测试代码,到底是哪里出错了,请大侠们指点下{:301_1009:} 本帖最后由 我的爱是你 于 2020-9-20 20:35 编辑
没仔细审题/ 谢谢楼主分享{:1_911:}{:1_911:}{:1_911:}
我的爱是你 发表于 2020-9-20 20:26
不懂你意思。
reallos直接对数组重新开辟大了2个int 在堆区你外部数组当然也会改变。
至于第二个说到底 ...
arr = (int *)realloc(arr, sizeof(int)*8);
*(arr+6) = *(temp+0);
*(arr+7) = *(temp+1);
print_arr(arr, 8);
free(temp);
指针交换,请问什么意思
*(arr+6) = *(temp+0);
*(arr+7) = *(temp+1);
这里不是在修改arr、arr的值吗。
最后释放temp的内存空间,怎么会连arr的值都给释放掉了
而且其余arr的值都乱了 跟内存分配有关系,你可以开个虚拟机,上个dos7.0试一试就知道是不是这回事了 建议你好好看看realloc的作用 百度百科:realloc重分配成功旧内存会被自动释放,旧指针变成了野指针。
在gen函数里更新的指针并没有传回到主函数中。
回到主函数后,打印野指针所以随机打印乱数。free野指针所以程序崩溃。 本帖最后由 volcanst 于 2020-9-20 23:27 编辑
假设使用realloc函数之前arr是A地址
使用之后arr就变成了B地址
A地址自动被释放了,但是gen函数并没有把现在的arr地址返回主函数
所以在主函数中arr还是A地址,但这时候A地址已经被释放了,所以是随机数,并且free函数想释放的还是A地址,可能会产生错误。
所以只需要在gen函数中返回arr的地址就可以了
volcanst 发表于 2020-9-20 23:20
假设使用realloc函数之前arr是A地址
使用之后arr就变成了B地址
谢谢。那为啥,第一串源代码里,同样也采用realloc函数,但在主函数里能正确打印
照你图示来看,下面这串代码,在gen函数里,调用realloc函数,arr不是也会更改地址?
gen函数同样也没把arr新地址传给主函数,但最后却能正确打印{:301_1007:}
另外,你这调试是VS自带的调试器,还能查看地址。不知道gdb能否{:301_998:}
#include <stdio.h>#include <stdlib.h>
#include <time.h>
void gen(int *arr);
void print_arr(int *arr, int num);
int main(int argc, const char *argv[])
{
srand(time(NULL));
int *arr = (int *)malloc(sizeof(int)*6);
gen(arr);
print_arr(arr, 8);
free(arr);
return 0;
}
void gen(int *arr)
{
int i;
for (i=0;i<6;i++) {
*(arr+i) = rand()%9+1;
}
arr = (int *)realloc(arr, sizeof(int)*8);
*(arr+6) = rand()%9+1;
*(arr+7) = rand()%9+1;
print_arr(arr, 8);
}
void print_arr(int *arr, int num)
{
int i;
printf("%s\n", __FUNCTION__);
for (i=0;i<8;i++) {
printf("%d ", *(arr+i));
}
printf("\n");
}
页:
[1]
2