qey

Atitude is Everything.-- 关注C/C++,关注Linux(Unix) ,关注网络。 Better Late Than Never.
随笔 - 4, 文章 - 13, 评论 - 7, 引用 - 0
数据加载中……

string 类型作为函数局部变量返回


string 类型作为函数返回对象的跟踪学习
因为以前教科书常说,不要返回一个局部变量的字符串(char[]);这样会得到意想不到的结果;
顾名思义地认为string 是字符串,作为局部变量返回不可取,实际上我大错特错,汲取教训。
string 作为局部变量,实际上只有string 的一些关键头信息位于“栈区”;主要字符数据位于“堆区”。
 与char* strTest[0x20] ="hello world!";全部位于栈区是不同的。

那么string 作为函数返回类型,又是如何操作的呢?我们知道,string 在作用完成后是会析构的。析构过程又是如何呢?

#include <iostream>
#include 
<cstdlib>
#include 
<string>

using namespace std;

string GetString()
{
    
//testing 001
    string strReturn;
    strReturn 
="abcedfghijklmnopqrstuvwxyz";
    
//"abcedfghijklmnopqrstuvwxyz"; 为静态数据,在数据区中存在,全局存在;
    
//strReturn 在赋值的时候,仅仅是将它copy 一份到堆中!
    
    
//cout<<"strReturn's addr:\t"<<"0X" << hex <<&strReturn<<endl;
    
//cout<<strReturn.c_str()<<endl;
    
    
//testing 002
    string str24R("");
    
int i;
    
for( i=0; i<strReturn.length(); i++)
    
{
        str24R 
+=strReturn[i];
    }

    
//cout<<"str24R's addr:\t"<<"0X" << hex <<&str24R<<endl;
    
//cout<<str24R.c_str()<<endl;
/*
    //testing 003
    string str34R;
    str34R =strReturn;
    cout<<"str34R's addr: "<<&str24R<<endl;
    cout<<str24R.c_str()<<endl;

    //testing 004
    char* charStr =new char[0x20];// ={0};
    for(i=0; i<10; i++)
    {
        charStr[i] =strReturn[i];
    }
    charStr[i] ='\0';
    cout<<"4 charStr's addr: "<<&charStr <<endl;
    cout<<charStr<<endl;

    //testing 005
    string str44R;
    str44R = charStr;
    cout<<"str44R's addr: "<<&str44R<<endl;
    cout<<str44R.c_str()<<endl<<endl;
    //delete []charStr;
*/

    
//return strReturn;         //返回正常
    return str24R;              //返回正常
    
//return str34R;            //返回正常
    
//return charStr;             //返回正常
    
//return str44R;

    
//test for pointer
    
//char *pstr;
    
//pstr =charStr;
    
//return pstr;
}


int GetItemID()
{
    
int i;
    i
=90*5;
    
return i;
}


int main()
{
    
char *pp =new char[1024];        //在堆里面分配
    
//test for returned string
    string strRecv;
    
//char *pp=GetString();
    strRecv =GetString();
    
    
char charpp[1024];        //    在栈里面分配
    string chstr("sometimes!");    

    cout
<<"strRecv's addr:\t"<<"0X" << hex <<&strRecv<<endl
        
<<strRecv.c_str()<<endl;
    
    
//cout <<&pp <<":"<<pp<<endl;
    
//delete []pp;                //testing for delete the memory which allocate in another function;
    
//pp=NULL;
    
    
//test for return int value
    int itemValue;
    delete []pp;

    itemValue 
=GetItemID();
    cout
<<endl<<dec<<itemValue<<endl;
    
return 0;
}


/*小小总结:
 *总结一下测试结果:当Getstring的返回值为string 类型时候,都是有效!
 *在退出被调用函数之前,向栈区 copy 了一份str24R string头(好像是三个dword)
 *(仅仅是str24R string头,放在栈区里面,指向堆的同一个地方);
 *在string 赋值后,就析构这个copy(在调用函数里面实现);
 
 *被调函数 在返回时 str24R析构的参数与一般的析构不同,为1或2(不delete堆区数据),
 *一般的析构为0(delete堆区数据)例如strReturn 在返回时,析构函数也删除了堆区数据;
 *在调用函数中 赋值后的copy 析构 原理同 被调函数 在返回时 str24R析构;

 *感觉有点类似于返回 字符串指针(用new 在堆里面分配内存)我们必须在手工delete 分配内存;
 *只是她用析构函数来自动完成,而不需要顾虑内存释放问题。
 *返回一个值时,不存在任何问题;
 */

posted on 2008-11-08 00:44 无声无色 阅读(5435) 评论(1)  编辑 收藏 引用 所属分类: 语言基础面试集合

评论

# re: string 类型作为函数局部变量返回  回复  更多评论   

实际上不用管那么多,可以认为函数返回一个值,这个值就是string类型;主要是因为string和char[] 有很大不同,char[]数据处于栈区,而string 的数据是处于堆区(new ??)。
2008-11-13 20:51 | 无声无色

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理