传递动态内存

当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。这些往往会使人受尽折磨,所以如果你想深入C/C++编程,你必须静下心来好好苦一番。

现在我们将讨论C/C++里我认为哪一本书都没有完全说清楚,也是涉及概念细节最多,语言中最难的技术之一的动态内存的传递。并且在软件开发中很多专业人员并不能写出相关的合格的代码。

【问题】下面的这个程序测试会有什么结果

#include <iostream>

void GetMemory(char* p,int num)
{
	p = (char*)malloc(sizeof(char) * num);
}

int main()
{
	char* str = NULL;
	GetMemory(str, 100);
	strcpy(str, "hello");

	system("pause");
	return 0;
}

【分析问题】
str始终为NULL,程序编译可以通过,但是运行会中断在 strcpy(str, "hello") 这行。

毛病出在函数GetMemory中。void  GetMemory(char* p, int num)中的p 实际上是主函数中str的一个副本,编译器总是要为函数的每个参数制作临时副本。在本例中,p申请了新的内存,只是把p所指的内存地址改变了,但是str丝毫未变。因为函数GetMemory没有返回值,因此str并不指向p所申请的那段内存。事实上,每执行一次GetMemory就会申请一块内存,但申请的内存却不会有效释放,结果内存一直被独占,有可能导致内存泄露。

【解决问题】

可以选择两种解决方法

1)采用指向指针的指针,传str的地址给函数GetMemory。代码如下:

#include <iostream>

void GetMemory(char** p,int num)
{
	*p = (char*)malloc(sizeof(char) * num);
}

int main()
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");

	std::cout << *str << std::endl
		<< str << std::endl
		<< &str << std::endl;

	system("pause");
	return 0;
}
这样的话,程序就可以运行成功。字符串是一个比较特殊的例子。我们分别打印*str,str,&str可以发现,结果分别是:h,hello,0027FEE4(这个不固定),str就是字符串的值,*str是字符串中某一字符的值,默认的是首字符,所以是h,&str是字符串的地址。

2)由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递内存。这个方法更加简单,代码如下:

#include <iostream>

char* GetMemory(char* p,int num)
{
	p = (char*)malloc(sizeof(char) * num);
	return p;
}

int main()
{
	char* str = NULL;
	str = GetMemory(str, 100);
	strcpy(str, "hello");

	system("pause");
	return 0;
}

PS: 摘自<程序员面试宝典>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值