代码如下void test1(const char * p)
{
printf("%s", p); //p数据正常
return;
}CStringA test(CStringA s)
{
return s;
}int main()
{ CStringA a = "abcd";
const char * p = test(a); //p数据正常
const char * p1 = test("abcd"); //p1乱码 test1(a);
return 0;
}
p1为什么数据会不正常?

解决方案 »

  1.   

    const char * p1 = test("abcd");        //p1乱码
    test 返回的是一个临时CStringA对象 ,
    这句执行完之后就销毁了
    也就是说P1 指向的是一个无效的地址
    这个地址里面是什么内容就不好说了
      

  2.   

    test("abcd");返回的是个临时对象,执行完就销毁了,,所以p1指向的内容是什么就不好说了
      

  3.   

    void test1(const char * p)
    {
        printf("%s", p);        //p数据正常
        return;
    }
    没返回 p啊?!
      

  4.   

    而且我很费解,const char * p1 = test("abcd");        
    p1是个char类型的指针,test的返回值是CStringA的对象,这句编译器居然会没报错?
      

  5.   

    const char* test1(const char * p) 

        printf("%s", p);        //p数据正常 
        return p; 

    试试
      

  6.   

    还是这位大虾厉害,直接就看出来了 test("abcd") 这个"abcd"字符串是临时的
      

  7.   

    恩 CStringA应该没有被完全销毁 返回值会创建一个副本的 有可能的是CStringA中的字符串属性"abcd"被释放了
    另外 如果是那样
    那么代码改成这样就可以正常得到数据了 CStringA str = test("abcd");
    const char * p2 = str; //p2正常
      

  8.   


    你查下地址就知道了 得到的是GetString()返回字符串的地址
      

  9.   


    按照 C++ 标准, 当临时对象不再被使用的时候, 编译器可以在合适的时机销毁该对象
    我跟了一下, const char * p1 = test("abcd"); 执行完, 临时对象就被销毁了
      

  10.   


    "abcd"是一定会被释放掉的,形参局部变量嘛 呵呵那你再试试这个呢
    test1(test("abcd"));
      

  11.   

    还有这个 CStringA str = test("abcd");
    const char * p2 = str;
      

  12.   

    这个问题应该不是和释放局部变量一回事
    因为
    char p3[8];
    strcpy(p3, "abcd");
    const char * p4 = test(p3);
    这么写p3绝对不会再test中被释放
      

  13.   

    你看一下汇编不就知道了 test1(test("abcd"));//p1乱码
    0041D2DA  push        ecx  
    0041D2DB  mov         ecx,esp 
    0041D2DD  mov         dword ptr [ebp-0ECh],esp 
    0041D2E3  mov         esi,esp 
    0041D2E5  push        offset string "abcd" (43A488h) 
    0041D2EA  call        dword ptr 
    // 构造临时 CString 对象
    [__imp_ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > >::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > > (444C7Ch)] 

    0041D2F0  cmp         esi,esp 
    0041D2F2  call        @ILT+5340(__RTC_CheckEsp) (4124E1h) 
    0041D2F7  mov         dword ptr [ebp-0F4h],eax 
    0041D2FD  lea         eax,[ebp-0E0h] 
    0041D303  push        eax  调用 test 函数
    0041D304  call        test (41216Ch) 0041D309  add         esp,8 
    0041D30C  mov         dword ptr [ebp-0F8h],eax 
    0041D312  mov         ecx,dword ptr [ebp-0F8h] 
    0041D318  mov         dword ptr [ebp-0FCh],ecx 
    0041D31E  mov         byte ptr [ebp-4],9 
    0041D322  mov         esi,esp 
    0041D324  mov         ecx,dword ptr [ebp-0FCh] 
    0041D32A  call        dword ptr [__imp_ATL::CSimpleStringT<char,1>::operator char const * (444C78h)] 
    0041D330  cmp         esi,esp 
    0041D332  call        @ILT+5340(__RTC_CheckEsp) (4124E1h) 
    0041D337  push        eax  调用 test1
    0041D338  call        test1 (412248h) 
    0041D33D  add         esp,4 
    0041D340  mov         byte ptr [ebp-4],8 
    0041D344  mov         esi,esp 
    0041D346  lea         ecx,[ebp-0E0h] 
    0041D34C  call        dword ptr // 销毁临时 CString 对象
    [__imp_ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > >::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > > (444C5Ch)] 

    0041D352  cmp         esi,esp 
    0041D354  call        @ILT+5340(__RTC_CheckEsp) (4124E1h) 
      

  14.   

    学习了,确实是CString调用了构造函数创建了临时对象,并根据为“abcd”分配了内存。
    返回前还根据临时对象再次构造CString对象,并使其m_pchData指向第一次构造的CString对象的数据内存。
    最后临时对象调用析构函数删除内存。
    因此p1不能指向常量“abcd”的地址,p1指向的是临时对象m_pchData的地址
      

  15.   


    const char * p1 = test("abcd"); //不正常
    CStringA str = test("abcd");  //正常
    p1和test中的s的m_pchData的地址是一样的 说临时地址释放了可以理解
    而str的m_pchData和test中s的m_pchData地址也是一样的 为什么没释放?或者说是释放了内容没清理?
      

  16.   


    void test1(const char * p)
    {
    printf("%s", p); //p数据正常
    return;
    }
    const char * p1 = CStringA("abcd"); //不正常
    test1(CStringA("abcd"));  //test1中正常拷贝构造和赋值运算符重载的问题?
    看看CString代码
      

  17.   


    呵呵 我用string代替CStringA在GCC下一切正常 在VC下还是有问题
      

  18.   

    第一个调用CSTRING类的拷贝构造函数,第二个是调用副值构造函数,在临时对象的生命周期到时,返回的自然是乱码,拷贝构造函数返回的是引用.