【问题标题】:Deleting Strings on the Heap Created from Char[] one the Heap in C++从 C++ 中的堆之一中删除从 Char[] 创建的堆上的字符串
【发布时间】:2013-08-27 00:07:13
【问题描述】:

我有一个相当简单的问题,我似乎找不到与 C++ std::string 相关的答案以及它是如何用 new 实例化的。现在,我很清楚从 new 返回的任何指针都应随后删除以防止内存泄漏。我的问题来自于随后使用现有指针实例化新字符串对象时会发生什么。请考虑以下简化示例:

char* foo() {
    char* ptr;

    ptr = new char[ARBITRARY_VALUE];
    ...
    ptr = strncpy("some null terminated string", ARBITRARY_VALUE)
    ...
    return ptr;
}

int main() {

    char* buf;
    std::string myStr;

    buf = foo();
    myStr = new std::string(buf);

    ...do stuff

    delete myStr;
    delete buf;         //Is this necessary?
    return 0;
}

我的问题很简单:删除 myStr 是否也会释放 buf 使用的底层内存,还是 buf 也需要手动释放? 如果 buf 必须手动释放,会发生什么情况匿名参数?如:

myStr = new std::string(foo());

我的怀疑是 std::string 的底层实现只维护一个指向字符缓冲区的指针,并且在销毁时释放 那个 指针,但我不确定,我的 C++ 充其量是生锈的.

额外问题:如果所讨论的类不是 std::string,这将如何改变?我假设对于任何用户创建的类,实现者必须提供显式析构函数,但是其他各种标准类呢?假设删除父对象总是足以完全破坏对象是否安全(我在这里尝试仔细挑选我的话;我知道在某些情况下不希望释放对象指向的内存,但这超出了这个问题的范围)?

【问题讨论】:

  • myStr = new std::string(buf); 不是有效代码。除非你打错了,myStrstd::string*
  • 请阅读并遵守它:klmr.me/slides/modern-cpp/#1
  • 是的,你需要删除buf,因为std::string 复制了它所指向的数据,原来的内存还在。不过,您可以使用delete[] buf;
  • myStr = new std::string(foo());内存泄露的情况下。
  • 请永远不要(!)返回分配的指针。除非它是分配器函数。

标签: c++ pointers memory-management stdstring


【解决方案1】:

std::string 可以从 C 风格的以空字符结尾的字符串 (const char *) 初始化。 std::string 无法知道您是否需要 const char * free()d、delete[]()d 或两者都不需要,并且如前所述,它不会。

使用智能指针自动删除动态分配的对象。其中有几种不同的,每种都专门用于特定目的。看看scoped_ptrauto_ptrshared_ptr。您的项目可能会限制您可以使用哪些智能指针。

在 C++ 上下文中,没有理由将字符串保存在手动声明的 char 数组中,std::string 使用起来更安全。

【讨论】:

    猜你喜欢
    • 2013-02-16
    • 2022-01-06
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 2020-12-04
    相关资源
    最近更新 更多