开辟动态内存的错误

实例1

char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}

运行结果

  我们来分析一波,先设置一个名为str的char类型的空指针,再构造一个创建了一个装有hello world的数组,将数组首元素的地址返回给str;

  生成的错误是显示了一串随机值,错误原因无非是越界访问,我们回到构造函数的里面,构造函数的参数是对实参的临时拷贝,所以p是临时拷贝出来的参数,在函数销毁是,将构造的p的数组的空间返回给操作系统,我们可以得到返回的空间的地址,将它传给str,但是那段空间已经还给了操作系统,我们无权访问,所以会生成一串随机值。

我们如何来修改这段代码呢,我们其实只需要让函数开辟的空间不返回给操作系统就行,我们可以在char p[]的前面加上static。这样就是在静态区开辟的空间,在整个程序结束后销毁。

 通常被称为返回栈空间地址的问题,实质就是在栈上开辟的空间,当栈区销毁后,我们无权访问它在栈上开辟的空间。即使我们知道它的地址。

实例2

 

void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}

 

 分析一下,我们创造一个空指针,再构造函数,将空指针传入函数,再函数内部开辟一个堆上的空间。

为什么什么都没有显示呢,显然是想让str开辟内存但是没有成功,参数里的p是对str的临时拷贝,p与str是两个独立的地址,毫不相干,这时将堆上开辟的内存地址传给了p,但是str还是空指针,所以在strcpy函数进行是就形成了非法访问,还有就是函数里开辟的内存没有返回给操作系统,造成了内存泄漏。

我们如何去更正呢,我们是想在str上开辟动态内存,那我们要使用传址调用去修改str的地址,我们在传参时传入str的二级指针也就是&str,然后再写函数时char* 改成char **,这下就不能用p去接收了,得用一级指针接受,*p去接收开辟的动态空间。在最后还要将str释放置为空。

实例3

void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}

这个跟实例2修改之后的很像 但是忘记了一个点,没有去释放str的动态内存,造成了内存泄漏,修改参考实例2的最后一句就行。

实例4

void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}

 这个咋一看运行结果没啥问题,其实代码时很有问题的,它在使用str之前竟然把str释放了,那你后面的访问也就构成了非法访问,这个问题太大,如果非要去更改的话,那就在释放str后将str置为空指针。

ok,感谢观看。欢迎指导。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值