【问题标题】:C++ std::string internal memory handling [duplicate]C ++ std :: string内部内存处理[重复]
【发布时间】:2013-08-25 12:29:47
【问题描述】:

我对 std::string 如何处理它的复制(?)内存感到困惑。

当我尝试这样做时:

char* abc = new abc[512];
abc = "abcdef";
std::string tempstr(abc);
tempstr[0] = 'Y';
std::cout << tempstr.c_str() << std::endl;
std::cout << abc << std::endl;

我得到以下输出:

Ybcdef
abcdef

但如果我尝试释放由 new 分配的内存,请在末尾添加:

delete [] abc;

我收到内存错误 (_BLOCK_TYPE_IS_VALID) 现在我的问题是,这怎么可能?字符串似乎复制了 abc 的数据,保持原样,但由于某种原因,我无法删除它。

我问这个,因为我的代码中有以下情况:

char* somestring = new char[1024];
// something happens to somestring here
stack.push_back(somestring); // stack is a vector of strings

我想知道我应该在哪里释放一些字符串分配的内存。

【问题讨论】:

  • 您正在尝试删除字符串文字。 new 在这里是非常不必要的。
  • abc = "abcdef"; 不会像你想的那样做......它重新分配一个指针,它确实将字符写入先前分配的内存中。
  • 不,这不可能那个难以掌握......不,不,不,我第一次明白这一点我已经读过了。再次通读该初学者的 C++ 教程,不要将 SO 与傻瓜混为一谈。

标签: c++ string memory-leaks


【解决方案1】:
char* abc = new abc[512];
abc = "abcdef";

使用这两个语句,您只是导致了内存泄漏,abc 不再指向动态内存,而是指向放置在只读内存中的字符串文字。所以当你打电话时:

delete [] abc;

您实际上是在一个未指向动态分配内存的指针上调用delete,这会导致未定义的行为并可能出现分段错误。

abc = "abcdef";

不会将字符串复制到分配给abc 的内存中,但它只是简单地重新设置abc 以指向字符串文字。为了能够将字符串复制到为abc 分配的内存中,您需要使用std::copystrncpy

【讨论】:

    【解决方案2】:
    char* abc = new abc[512];
    
           +-----------------------+
    abs -> | 512 byte memory block |
           +-----------------------+
    
    
    abc = "abcdef";
    
           +-----------------------+
           | 512 byte memory block |
           +-----------------------+
    
           +----------+
    abs -> | abcdef\0 |
           +----------+
    
    
    std::string tempstr(abc);
    
           +-----------------------+
           | 512 byte memory block |
           +-----------------------+
    
           +----------+
    abs -> | abcdef\0 |
           +----------+
    
                    +----------+
    temp.c_str() -> | abcdef\0 |
                    +----------+
    
    
    tempstr[0] = 'Y';
    
           +-----------------------+
           | 512 byte memory block |
           +-----------------------+
    
           +----------+
    abs -> | abcdef\0 |
           +----------+
    
                    +----------+
    temp.c_str() -> | Ybcdef\0 |
                    +----------+
    

    【讨论】:

      【解决方案3】:

      您没有通过分配的指针进行删除,并且您的程序具有未定义的行为。

      abc = "abcdef";
      

      abc 现在指向 static 存储持续时间的字符串文字的开头。您不能修改或删除它。原来的指针,丢失了,你分配的内存泄露了。

      你可以(以及我认为你想要)做什么:

      char* abc = new abc[512];
      const char* s = "abcdef"; // note the const - assigning a pointer to string literal to 
                                // char* is illegal in C++11
      std::copy(s, s+6, abc);
      

      是的,std::string 拥有字符串的内容,它从abc 复制它。

      【讨论】:

        【解决方案4】:

        您没有分配abc 指向的内存:它来自字符串文字。因此,您不得以任何方式删除内存或修改内容。当 std::string 从字符串文字构造时,它会创建字符串文字的副本并在内部维护此副本所需的内存。

        【讨论】:

          猜你喜欢
          • 2011-08-06
          • 1970-01-01
          • 2013-01-15
          • 1970-01-01
          • 2019-09-16
          • 1970-01-01
          • 2021-02-19
          • 1970-01-01
          • 2011-02-10
          相关资源
          最近更新 更多