代码如下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为什么数据会不正常?
{
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为什么数据会不正常?
test 返回的是一个临时CStringA对象 ,
这句执行完之后就销毁了
也就是说P1 指向的是一个无效的地址
这个地址里面是什么内容就不好说了
{
printf("%s", p); //p数据正常
return;
}
没返回 p啊?!
p1是个char类型的指针,test的返回值是CStringA的对象,这句编译器居然会没报错?
{
printf("%s", p); //p数据正常
return p;
}
试试
另外 如果是那样
那么代码改成这样就可以正常得到数据了 CStringA str = test("abcd");
const char * p2 = str; //p2正常
你查下地址就知道了 得到的是GetString()返回字符串的地址
按照 C++ 标准, 当临时对象不再被使用的时候, 编译器可以在合适的时机销毁该对象
我跟了一下, const char * p1 = test("abcd"); 执行完, 临时对象就被销毁了
"abcd"是一定会被释放掉的,形参局部变量嘛 呵呵那你再试试这个呢
test1(test("abcd"));
const char * p2 = str;
因为
char p3[8];
strcpy(p3, "abcd");
const char * p4 = test(p3);
这么写p3绝对不会再test中被释放
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)
返回前还根据临时对象再次构造CString对象,并使其m_pchData指向第一次构造的CString对象的数据内存。
最后临时对象调用析构函数删除内存。
因此p1不能指向常量“abcd”的地址,p1指向的是临时对象m_pchData的地址
const char * p1 = test("abcd"); //不正常
CStringA str = test("abcd"); //正常
p1和test中的s的m_pchData的地址是一样的 说临时地址释放了可以理解
而str的m_pchData和test中s的m_pchData地址也是一样的 为什么没释放?或者说是释放了内容没清理?
void test1(const char * p)
{
printf("%s", p); //p数据正常
return;
}
const char * p1 = CStringA("abcd"); //不正常
test1(CStringA("abcd")); //test1中正常拷贝构造和赋值运算符重载的问题?
看看CString代码
呵呵 我用string代替CStringA在GCC下一切正常 在VC下还是有问题