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

时间:2015-07-01 20:39:52

标签: c++ memory memory-leaks

我还是比较新的C ++,但我主要使用C ++ 11的功能,这通常可以避免内存泄漏。仍然,与其他较旧的库一起使用,不幸的是,我需要与旧代码接口。

我见过类似的问题,但是在没有new的情况下,无法轻易找到分配数组的地方。例如,所以它是在堆栈而不是堆,我的理解。

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

ConfigStruct {
  const char *word;
}

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

我相信这个配置对象将被传递到一个单独的低级函数中。但是,我很难在这种情况下解决内存责任的问题。低级库是唯一可以释放该字符串内存的东西吗?是否会自动使用ConfigStruct进行破坏?或者,在此函数结束时,该内存是否会被不恰当地标记为“空闲”,并可能导致配置对象稍后出现?

编辑:最后一个问题;如果ConfigStruct无法更改,我的任务是编写一个返回generateConfigStruct的{​​{1}},有没有办法做到这一点,不会导致以后使用任何问题,和可以某种方式保证记忆安全吗?

3 个答案:

答案 0 :(得分:1)

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

编辑以解决后续行动:只是说

会更安全
cfg.word = "word";

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

否则你会被卡住 - 你可以分配内存并让cfg.word指向它,但是你有泄漏。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

  

但是,我很难在这种情况下解决内存责任问题。低级库是唯一可以释放该字符串内存的东西吗?

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

cfg.word = myWord;
return cfg;

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

  

它会自动被ConfigStruct破坏吗?

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

  

或者,在此函数结束时,该内存是否会被不恰当地标记为“空闲”,并可能导致配置对象稍后出现?

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

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

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

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