堆栈分配的数组是否可能发生内存泄漏

Is a memory leak possible with a stack-allocated array?

本文关键字:可能发生 内存 泄漏 是否 数组 分配 堆栈      更新时间:2023-10-16

我对C++还比较陌生,但我主要使用C++11功能,这些功能通常可以避免内存泄漏。尽管如此,在使用其他较旧的库时,不幸的是,有时我需要使用较旧的代码。

我看到过类似的问题,但在没有new的情况下,无法轻松找到数组的分配位置;例如,据我所知,它在堆栈上而不是堆上。

这种情况恰好涉及字符串,但机制可能更多地与数组有关。

ConfigStruct {
  const char *word;
}
ConfigStruct generateConfigStruct() {
  const char myWord[] = "word"; // <-- This
  ConfigStruct cfg;
  cfg.word = myWord;
  return cfg;
}

我相信这个配置对象将被传递到一个单独的较低级别函数中。但是,我很难弄清楚在这种情况下,记忆的责任应该在哪里。低级库是唯一可以释放该字符串内存的东西吗?它会自动被ConfigStruct破坏吗?或者,在该函数结束时,该内存是否会被不适当地标记为"空闲",并可能导致以后的配置对象问题?

编辑:最后一个问题;如果ConfigStruct不能更改,而我的任务是编写一个返回ConfigStructgenerateConfigStruct,有没有任何方法可以做到这一点,不会导致以后的使用问题,可以在某种程度上保证内存安全,尽管有悬挂的指针?

myWord确实在堆栈上,所以它不是静态分配的——它是自动分配的。当函数退出时,它会被破坏——这是一个问题,因为cfg仍然有一个指向它的指针

编辑以解决后续问题:只说会更安全

cfg.word = "word";

然后,您有一个指向常量字符串的指针,该字符串将持续整个程序的持续时间。

否则,您将陷入困境——您可以分配内存并使cfg.word指向它,但随后会发生泄漏。

您声明了一个将在堆栈上分配的局部变量。当函数generateConfigStruct()返回时,它的调用帧从堆栈中弹出。下一个被调用的方法将有一个调用帧,然后被推送到堆栈上,并可以覆盖该位置的数据。

您不希望返回指向堆栈分配的存储的指针。

但是,我很难弄清楚在这种情况下,记忆的责任应该在哪里。低级库是唯一可以释放该字符串内存的东西吗?

在发布的代码中,字符串文字"word"的内存由运行时库管理。字符串文字位于程序的只读部分。该内存在程序的生命周期内有效。但是,您还有一个堆栈变量myWord。它保存一份"word"myWord使用的内存在函数执行期间有效,在函数返回时变为无效。通过使用:

cfg.word = myWord;
return cfg;

您返回的对象保留了一个无效的指针。

它会自动被ConfigStruct破坏吗?

ConfigStruct的析构函数是否试图为其成员veriable word解除分配内存取决于ConfigStruct的定义。如果它没有用户定义的析构函数,那么编译器会生成一个,但编译器生成的析构因子不会释放word使用的内存。

或者,在该函数结束时,该内存是否会被不适当地标记为"空闲",并可能导致以后的配置对象问题?

这是正确的。如果稍后使用返回的ConfigStruct对象的word成员变量,则会遇到问题,因为这是一个悬空指针。

如果ConfigStruct没有用户定义的析构函数,可以使用:

ConfigStruct generateConfigStruct() {
  static char myWord[] = "word";
  ConfigStruct cfg;
  cfg.word = myWord;
  return cfg;
}

ConfigStruct generateConfigStruct() {
  ConfigStruct cfg;
  cfg.word = "word";
  return cfg;
}