-
c++用参数返回堆上的空间
添加时间:2013-7-26 点击量:《高质量c++和c编程》7.4 指针参数是如何传递内存的一节中写道
void GetMemory(char p, int num)
{
p = (char )malloc(sizeof(char) num);
}
void Test(void)
{
char str = NULL;
GetMemory(str, 100); // str 仍然为 NULL
strcpy(str, hello); // 运行错误
}无法返回内存,可以用如式格式
void GetMemory2(char p, int num)
{
p = (char )malloc(sizeof(char) num);
}
void Test2(void)
{
char str = NULL;
GetMemory2(&str, 100); // 重视参数是 &str ,而不是str
strcpy(str, hello);
cout<< str << endl;
free(str);
}小我的懂得就是,实际上指针传递仍然是一种值传递,只不过在参数是指针的时辰,传递的是指针的副本,如许你在地址上的操纵实际就反应到了内存中,举个例子来说,假设有一个函数
void fun(int p)
{
p = new int;
}当用调用时fun(q),会产生实参的一个副本设为_p,函数体为副本_p分派了内存,实际上并未改变实参p,这就是GetMemory没有成功的原因。相反,若是我们有如下函数
void fun(int p)
{
p = 3;
}在这个函数中,当产生实参调用的时辰,仍然会产生实参的副本,然则重视这里不是改变副本,而是改变副本指向的内存中的内容,这里p是一个整形指针,在内存中占四个字节,副本和实参指向同一片内存,所以当你
在以副本为地址的内存内赋值3,实际也就是改变了实参指向的内存中的内容。
总结一下就是:指针传递仍然是值传递,所以我们在函数体内只有操纵p才会达到我们的指针传递请求,而不是操纵p,如许操纵只在副本上,实际并不反应到实参指向的内存。
书中另一种办法是:
char GetMemory3(int num)
{
char p = (char )malloc(sizeof
return p;
}
void Test3(void)
{
char str = NULL;
str = GetMemory3(100);
strcpy(str, hello);
cout<< str << endl;
free(str);
}实际是将堆的特点和return相连络,堆上分派的内存在函数不会开释,而return实际返回的p的一个副本,然则这里的副本是一个指针,简单的说是一个内存地址,而这个地址在函数停止后并没有开释,所以,我们可以持续
应用。若是是通俗的局部变量,return返回它的一个副本,随后局部变量跟着函数的停止而被开释,这在某些时辰会引起麻烦,比如
char GetString(void)
{
char p[] = hello world;
return p; // 编译器将提出警告
}
void Test4(void)
{
char str = NULL;
str = GetString(); // str 的内容是垃圾
cout<< str << endl;
}至于return似乎还有器材说,一时想不起。。。
工作总有例外,今天小妞找我调试法度,发了然一件很独特的工作,看代码
void getArray(char s, int N)
{
std::ifstream in(test.txt);
if (!in.is_open())
{
std::cout<<error<<std::endl;
}
int i = 0;
while(i < N)
{
s[i] = (char)malloc(sizeof(char)100);
in.getline(s[i], 100);
++i;
}
in.close();
}
int main()
{
char s = (char )malloc(sizeof(char) 4);
getArray(s, 4);
for (int i=0; i<4; i++)
{
std::cout<<s[i]<<std::endl;
}
return 0;
}这个法度可以正确编译履行。而下面代码
void getArray1(char s, int N)
{
// s = (char )malloc(sizeof(char) 4);
s = new char[4];
std::ifstream in(test.txt);
if (!in.is_open())
{
std::cout<<error<<std::endl;
}
int i = 0;
while(i < N)
{
// s[i] = (char)malloc(sizeof(char)100);
s[i] = new char[100];
in.getline(s[i], 100);
++i;
}
in.close();
}
int main()
{
char s;
getArray1(s, 4);
for (int i=0; i<4; i++)
{
std::cout<<s[i]<<std::endl;
}
return 0;
}这个代码确切在运行时失足
解析了一下,小我认为固然两个函数的参数都是char s,然则一个在main()中先分派,一个直接在getArray平分派,原因就在于此,getarray函数在main函数中先分派了内存,然后传递给它,固然仍然是值传递,然则
s的元素是指针,getarray函数中在main函数分派的内存上完成了操纵,所以当函数停止时,所有操纵仍然保存下来。getarray1函数不合,它是在函数体内完全分派内存,然后施加操纵的,相当于都在副本上,所有操纵都不会
在函数停止后保存下来。
这是小我的一点懂得,如有不合错误的处所还请指教。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》