指针问题

shuaiwang_01 2011-03-07 02:39:08

#include <iostream>
using namespace std;
class B
{
public:
char* str;

B(){}
B(char* s)
{
str = s;
}

~B()
{
printf("B\n");
delete str;
}
};
class A
{
public:
B b;

A(){}
A(B bb)
{
b = bb;
}

~A()
{
printf("A\n");
}
};


int main()
{
char* objectStr = new char[5];
for(int i = 0; i < 4; i++)
objectStr[i] = 'a';
objectStr[4] = '\0';
B* objectB = new B(objectStr);
printf("%s\n", objectB->str);
A* objectA = new A(*objectB);
//delete objectA;
/*delete objectB;
delete objectA;*/
//printf("%s", objectB->str);
printf("%s\n", objectB->str);
return 0;
}


为什么*objectB之后printf("%s\n", objectB->str);就变了,好像被释放了一样
...全文
223 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
fendouzhe 2011-03-08
  • 打赏
  • 举报
回复
发现两个问题:
1 new出来的数组需要用delete [] 来删除
2 需要重新定义拷贝构造函数,对指针成员需要进行深拷贝。
shaotine_wu 2011-03-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 linuxbirdman 的回复:]

A(B& bb)
{
b = bb;
}这样就OK乐。。
[/Quote]
正确方法,+++
碎碎念 2011-03-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bdmh 的回复:]

B的带参数的构造函数中,直接给str改掉了
[/Quote]
++
striving_boy 2011-03-07
  • 打赏
  • 举报
回复
楼上说的很清楚呀!!呵呵。。。佩服!!
newfarmerchi 2011-03-07
  • 打赏
  • 举报
回复


/*
1. 主要是B的默认拷贝构造函数没有处理好指针,发生了str已被析构,程序的
最后语句要求打印(printf("%s\n", objectB->str);)。
2. 从新定义一个B(const B& temp)和重载一个 = 赋值运算符,采用深层复制的方法,就可以了。
*/


#include <iostream>
#include <cstring>
using namespace std;
class B
{
public:
char* str;

B(){}
B & operator=(const B& x)
{
cout<<"调用赋值运算符重载"<<endl;
if (this != &x)
{
str=new char [strlen(x.str)+1];
strcpy(str , x.str);

}
return *this;
}
B(const B& temp)
{
cout<<"调用拷贝构造函数"<<endl;
str=new char [strlen(temp.str)+1];
strcpy(str , temp.str);
}
B(char* s)
{
if (s==NULL)
{
str=new char [2];
strcpy(str,"");
}
else
{
str=new char [strlen (s)+1];
strcpy( str, s);
}
}

~B()
{
printf("B\n");
delete str;
str=NULL;
}
};
class A
{
public:
B b;

A(){}
A(B bb)
{
cout<<"A生成了"<<endl;
b = bb;
}

~A()
{
printf("A\n");
}
};


int main()
{
char* objectStr = new char[5];
for(int i = 0; i < 4; i++)
objectStr[i] = 'a';
objectStr[4] = '\0';
B* objectB = new B(objectStr);//这是第一个B
printf("%s\n", objectB->str);
A* objectA = new A(*objectB);//括弧里的*objectB先调用B的拷贝构造函数
// 然后调用=运算符重载。

printf("%s\n", objectB->str);//仍然可以打出第一个B的str。
delete objectA;//delete A,然后A里的B也被析构了。
delete objectB;//delete 这是第一个B。
return 0;
}





豆哥要做MT 2011-03-07
  • 打赏
  • 举报
回复
你单步看看程序的运行过程

后面调用了B类的析构函数
~B()
{
printf("B\n");
delete str;
}
这里的str指向的就是objectStr
delete str就释放啦,你懂得
LinuxBirdMan 2011-03-07
  • 打赏
  • 举报
回复
A(B& bb)
{
b = bb;
}这样就OK乐。。

LinuxBirdMan 2011-03-07
  • 打赏
  • 举报
回复
A(B& bb)
{
b = bb;
}

Johnxme126 2011-03-07
  • 打赏
  • 举报
回复
好像*objectB就会调用析构函数
改成A(B* bb)
A* objectA = new A(objectB);
就行了
bdmh 2011-03-07
  • 打赏
  • 举报
回复
B的带参数的构造函数中,直接给str改掉了
S_aladdin 2011-03-07
  • 打赏
  • 举报
回复
B的构造函数就是直接赋值指针阿,应该在B内分配内存然后把字符串内容拷贝过去吧

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧