gpt4 book ai didi

c++ - 在 C++ 中重新分配指针的正确方法

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:05:59 25 4
gpt4 key购买 nike

编辑:我知道在这种情况下,如果它是一个实际的类,我最好不要将字符串放在堆上。但是,这只是一个示例代码,以确保我理解该理论。实际代码将是一棵红黑树,所有节点都存储在堆上。

我想确保在继续之前我的这些基本想法是正确的(我来自 Java/Python 背景)。我一直在网上搜索,但还没有找到这个问题的具体答案。

当您将指针重新分配给新对象时,是否必须先对旧对象调用 delete 以避免内存泄漏?我的直觉告诉我是的,但在继续之前我想要一个具体的答案。

例如,假设您有一个存储指向字符串的指针的类

class MyClass
{
private:
std::string *str;

public:
MyClass (const std::string &_str)
{
str=new std::string(_str);
}

void ChangeString(const std::string &_str)
{
// I am wondering if this is correct?
delete str;
str = new std::string(_str)

/*
* or could you simply do it like:
* str = _str;
*/
}
....

在 ChangeString 方法中,哪个是正确的?

如果您不对第二种方式使用 new 关键字,我想我会挂断电话,它仍然会像您预期的那样编译和运行。这是否只是覆盖了这个指针指向的数据?或者它还有别的作用吗?

任何建议都将得到极大的应用 :D

最佳答案

如果您必须释放旧实例并创建另一个实例,您应该首先确保创建新对象成功:

void reset(const std::string& str)
{
std::string* tmp = new std::string(str);
delete m_str;
m_str = tmp;
}

如果你先调用delete,然后创建一个新的抛出异常,那么类实例就会留下一个悬空指针。例如,您的析构函数最终可能会再次尝试删除指针(未定义的行为)。

您也可以通过将指针设置为 NULL 来避免这种情况,但上述方法仍然更好:如果重置失败,对象将保持其原始值。


关于代码注释中的问题。

*str = _str;

这才是正确的做法。这是正常的字符串赋值。

str = &_str;

这将是分配指针并且是完全错误的。您会泄漏先前由 str 指向的字符串实例。更糟糕的是,传递给函数的字符串很可能一开始就没有用 new 分配(您不应该混合指向动态分配对象和自动对象的指针)。此外,您可能正在存储一个字符串对象的地址,该对象的生命周期以函数调用结束(如果 const 引用绑定(bind)到一个临时对象)。

关于c++ - 在 C++ 中重新分配指针的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2654415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com