一个C语言典型的内存泄露问题

具体的问题见下面的demo:

#include <stdio.h>

void getheap(int *p)//p是NULL的地址
{
	p = malloc(sizeof(int) * 10); //p重新指向了分配在堆中的空间
}//形式参数int *p在栈空间内,函数结束后就释放了,malloc分配的空间也丢失了,同样也没有带回实参


int main()
{
	int *p = NULL;  //NULL就是(void *)0
	printf("p=%p\n", p);//p是null的地址
	printf("p=%p\n", &p);//&p是p本身的地址

	getheap(p);//值传递,将NULL的地址传递给形参

	p[0] = 10;
	p[1] = 20;

	printf("p[0]=%d,p[1]=%d\n",p[0],p[1]);
	
	free(p);//p中不是堆中分配的空间的首地址,故free(p)也有问题

	return 0;
}
运行:


原因:


改正如下:

#include <stdio.h>


void getheap(int **p)// p就是s实参p的地址
{
	*p = malloc(sizeof(int) * 10);//将在堆中分配的空间的地址赋值给实参p,即实参p就是在堆中分配空间的地址
}//函数调用结束后,实参p的值就是在堆中分配空间的首地址

int main()
{
	int *p = NULL;

	getheap(&p);//将指针p本身的地址传递给形参

        p[0] = 10;
	p[1] = 20;

	printf("p[0]=%d,p[1]=%d\n", p[0], p[1]);

	free(p);//p的值就是在堆中分配空间的首地址

	return 0;
}
运行正常:

因为:

其中0x100是p本身的地址,形参里**p的p就是0x100,

*p=malloc(sizeof(int) *10);假设分配的空间地址是0x123,  相当于将main函数里面的p=0x123,即p指向了分配的空间的首地址;


int *getheap2()//正确:把申请的堆的地址返回
{
	return malloc(100);
}


char *getstring()//错误:array是在栈中的,函数结束后,地址消失
{
	char array[10]="hello";
	return array;
}


char getstring1()//正确:返回的是值,不是地址,即便c是栈中的变量,即便地址消失了
{
	char c='a';
	return c;
}


const char *getstring2()//正确:常量在静态区,地址在程序运行的时候一直存在
{
	return "hello";//可以将一个常量的地址作为一个函数的返回值返回
} 


char *getstring3()//正确:
{
	static char array[10]="hello";//在静态区
	return array;
}


int main()
{
	int *p=NULL;
	
	p=getheap2();//正确
	
	char *s=getstring();//错误
	
	char c=getstring1();//正确
	
	const char *s1=getstring2();//正确
	
	const char *s2=getstring3();
	
	
	return 0;
}



  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当涉及到内存泄漏时,我们需要使用一些工具来检测和解决这个问题。其中一个常用的工具是 Valgrind,它可以检测内存泄漏和其它内存错误。以下是一个简单的 C 语言程序,使用 Valgrind 来检测内存泄漏: ``` #include <stdlib.h> int main() { int *ptr = malloc(sizeof(int)); *ptr = 42; free(ptr); return 0; } ``` 在终端中运行以下命令: ``` valgrind --leak-check=full ./a.out ``` Valgrind 将会输出内存泄漏的详细信息,如果没有内存泄漏,它将会输出类似于以下的信息: ``` ==12345== HEAP SUMMARY: ==12345== in use at exit: 0 bytes in 0 blocks ==12345== total heap usage: 1 allocs, 1 frees, 4 bytes allocated ==12345== ==12345== All heap blocks were freed -- no leaks are possible ==12345== ==12345== For counts of detected and suppressed errors, rerun with: -v ==12345== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` 如果有内存泄漏,它将会输出类似于以下的信息: ``` ==12345== HEAP SUMMARY: ==12345== in use at exit: 4 bytes in 1 blocks ==12345== total heap usage: 2 allocs, 1 frees, 8 bytes allocated ==12345== ==12345== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==12345== by 0x4005B7: main (in /path/to/program) ==12345== ==12345== LEAK SUMMARY: ==12345== definitely lost: 4 bytes in 1 blocks ==12345== indirectly lost: 0 bytes in 0 blocks ==12345== possibly lost: 0 bytes in 0 blocks ==12345== still reachable: 0 bytes in 0 blocks ==12345== suppressed: 0 bytes in 0 blocks ==12345== ==12345== For counts of detected and suppressed errors, rerun with: -v ==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ``` 这个程序中没有内存泄漏,所以 Valgrind 输出了 "no leaks are possible" 的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值