c++类指针删除段错误
我有一个名为 object
的简单类,但我遇到了问题。如果我调用一种方法,它会导致段错误。我不明白为什么。
typedef class object
{
private:
short id;
std::string name;
SDL_Rect offset;
public:
object();
object(short i, std::string n);
~object();
object(const object &o);
object& operator = (const object &o);
std::string get_name();
void set_name(std::string n);
} object;
object::object()
{
id = 0;
name = "";
offset.x = 0;
offset.y = 0;
offset.w = 0;
offset.h = 0;
}
object::object(short i, std::string n)
{
id = i;
name = n;
offset.x = 0;
offset.y = 0;
offset.w = 0;
offset.h = 0;
}
object::~object()
{
delete &offset;
delete &id;
delete &name;
}
object& object::operator=(const object &o)
{
if(this != &o)
{
delete &name;
name.assign(o.name);
delete &id;
id = o.id;
delete &offset;
offset = o.offset;
}
return *this;
}
object::object(const object &o)
{
id = o.id;
name = o.name;
offset = o.offset;
}
// Functions
std::string object::get_name()
{
return name;
}
void object::set_name(std::string n)
{
name = n;
}
而我的 main.cpp
int main( int argc, char** argv )
{
struct object *a = new object(0, "test");
struct object *b = new object(1, "another test");
printf(a->get_name().c_str());
printf("\n");
printf(b->get_name().c_str());
b = a;
printf("\n");
printf(b->get_name().c_str());
a->set_name("Another test");
printf("\n");
printf(a->get_name().c_str());
delete a;
printf("\nDeleted a");
delete b;
printf("\nDeleted b");
return 0;
}
如果我调用 a->set_name("Another test");
,我会遇到段错误。如果我不打电话,就没有问题,一切正常。我可能错过了一些简单的东西,但我找不到它。它不会在分配时出现段错误,但如果该行在那里,则在删除指针时会崩溃。
I've got a simple class called object
that I'm having a problem with. Theres one method which causes a segfault if I call it. I don't understand why.
typedef class object
{
private:
short id;
std::string name;
SDL_Rect offset;
public:
object();
object(short i, std::string n);
~object();
object(const object &o);
object& operator = (const object &o);
std::string get_name();
void set_name(std::string n);
} object;
object::object()
{
id = 0;
name = "";
offset.x = 0;
offset.y = 0;
offset.w = 0;
offset.h = 0;
}
object::object(short i, std::string n)
{
id = i;
name = n;
offset.x = 0;
offset.y = 0;
offset.w = 0;
offset.h = 0;
}
object::~object()
{
delete &offset;
delete &id;
delete &name;
}
object& object::operator=(const object &o)
{
if(this != &o)
{
delete &name;
name.assign(o.name);
delete &id;
id = o.id;
delete &offset;
offset = o.offset;
}
return *this;
}
object::object(const object &o)
{
id = o.id;
name = o.name;
offset = o.offset;
}
// Functions
std::string object::get_name()
{
return name;
}
void object::set_name(std::string n)
{
name = n;
}
And my main.cpp
int main( int argc, char** argv )
{
struct object *a = new object(0, "test");
struct object *b = new object(1, "another test");
printf(a->get_name().c_str());
printf("\n");
printf(b->get_name().c_str());
b = a;
printf("\n");
printf(b->get_name().c_str());
a->set_name("Another test");
printf("\n");
printf(a->get_name().c_str());
delete a;
printf("\nDeleted a");
delete b;
printf("\nDeleted b");
return 0;
}
If I call a->set_name("Another test");
, I get a segfault. If I leave out the call, no problems, everything works. I'm probably missing something simple, but I can't find it. It doesn't segfault on the assignment, but if that line is there it crashes when deleting the pointer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于您没有在构造函数中
new
任何内容,因此在析构函数中delete
任何内容都是错误的。只需将析构函数留空即可,或者更好的是,完全摆脱它。编译器生成的析构函数完全按照您的要求执行(什么都不执行)。您也不必手动编写复制构造函数和复制赋值运算符,只需将它们扔掉即可。也不需要动态创建对象,并且使用本机 C++ 输入/输出工具打印字符串要容易得多。并且您可以摆脱使用默认参数重载构造函数的情况。通过引用 const 来传递和返回字符串比通过值传递字符串更有效。最后但并非最不重要的一点是,让我们保持 const 正确。这是我对您的代码的清理:
Since you didn't
new
anything in the constructor, it is wrong todelete
anything in the destructor. Just leave the destructor empty, or even better yet, get rid of it completely. The compiler-generated destructor does exactly what you want (nothing). You also don't have to write the copy constructor and the copy assignment operator by hand, just throw them away.There is also no need to create the objects dynamically, and printing strings is a lot easier with the native C++ input/output facilities. And you can get rid of overloading the constructor with default arguments. And passing and returning strings by reference-to-const is more efficient than passing them by value. Last but not least, let's be const correct. Here is my cleanup of your code:
您只能
删除
通过调用new
获得的指针。name
是类的成员变量;您无法删除它,也永远不需要删除它。当类被销毁时,它也会销毁所有成员变量。仅当您的成员是指针时(例如,如果您有
std::string* name
),您就必须确保正确清理它们,但即便如此,您也应该更喜欢使用 smart诸如scoped_ptr
、shared_ptr
或unique_ptr
之类的指针(如果您的实现支持的话)。You can only
delete
pointers that you obtained by callingnew
.name
is a member variable of the class; you can't delete it, nor will you ever have to. When the class is destroyed, it will destroy any member variables as well.It's only if you have members that are pointers (like if you had
std::string* name
) that you would have to be sure to properly clean them up, but even then you should prefer to use smart pointers likescoped_ptr
,shared_ptr
, orunique_ptr
(if your implementation supports it).name
是一个string
并管理自己的内存。您在结构中的声明是正确的,您可以在已经存在的任何值之上分配
。当结构超出范围时也无需执行任何操作。请注意,您的 get_name 方法返回一个新副本,因为它按值返回。您可以像这样返回对结构中内容的引用,前提是在所属结构超出范围后不使用返回值:
您应该按如下方式更改 setter 声明,因为传递副本没有任何好处(过多传递按值是新 C++ 开发人员中的常见错误)。
name
is astring
and manages its own memory. Your declaration in the struct is correct, you can justassign
on top of any value that's already there. No need to do anything when the struct goes out of scope either.Note that your get_name method returns a new copy since it returns by value. You could instead return a reference to what's in the struct like this, provided the returned value is not used after the owning struct goes out of scope:
You should change the setter declaration as follows, since there's no benefit in passing a copy (excessive pass by value is a common error among new C++ developers).