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函数不合,它是在函数体内完全分派内存,然后施加操纵的,相当于都在副本上,所有操纵都不会
在函数停止后保存下来。
这是小我的一点懂得,如有不合错误的处所还请指教。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》
                     
                  
     
  
 
    
    
《高质量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函数不合,它是在函数体内完全分派内存,然后施加操纵的,相当于都在副本上,所有操纵都不会
在函数停止后保存下来。
这是小我的一点懂得,如有不合错误的处所还请指教。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》



