【问题标题】:Heap corruption by strings字符串的堆损坏
【发布时间】:2014-09-05 17:38:41
【问题描述】:

假设我有这段代码

void someFunction(args..) {
 char array[4];
 array[0] = 'a';
 array[1] = 'b';
 array[2] = 'c';
 array[3] = 'd';
}

基本上,我得到的是数组末尾没有'\0'。 当我们离开这个函数时,array[] 被释放了——对吧?最后没有'\0'符号的事实会导致堆损坏吗?如果这样的功能经常出现怎么办?如果我这样做是不是一样:

void someFunction(args..) {
 char* array = new char[4];
 array[0] = 'a';
 array[1] = 'b';
 array[2] = 'c';
 array[3] = 'd';
 //and now i dont call 
 //delete array;
}

提前感谢您的帮助! :)

【问题讨论】:

  • 你为什么使用 C 风格的字符串?这在很大程度上取决于您对array 的处理方式。
  • “基本上,我的意思是没有'\0' ...”如果你不放一个,你为什么会期待一个那里?将您的数组定义为char array[5]; 并为您的两个代码示例输入array[4] = '\0';!这与堆栈或堆无关。

标签: c++ string char heap-corruption


【解决方案1】:

不,这两种情况都不会导致堆损坏。

终止空字符用于向库函数发出字符串结束的信号。您在这里没有使用任何库函数。

在第一种情况下,数组是在堆栈上分配的,并且您给出一个确切的大小 (4)。当函数被调用时,堆栈指针将减少到足以为这个变量增加空间,当它返回时,堆栈指针将增加相同的量。数组的实际内容(包括是否存在任何空终止字符)对这个过程完全没有影响。

您的第二种情况会导致内存泄漏,但仍然不会导致堆损坏,因为 - 再次 - 您没有将指针与任何期望它的库函数一起使用。

【讨论】:

  • 谢谢!如果我有很多这样分配的地方: char *array = new char[...] 基本上,很多泄漏,这会导致我的应用程序写入堆尾后面的内存吗?
  • @Alek988Alek 不,这只是意味着在您的程序终止之前,操作系统无法回收内存。我强烈建议您使用std::string,除非您有特定的理由不这样做,因为它会自动为您管理这些内存分配。
  • 另一个跟进,我真的在这里失去理智,如果我声明这样的函数: void function(char*) 并且它用它的参数做了一些事情;然后我这样称呼它: char array[] { "abcd" };函数(数组);这会造成破坏,对吧?我应该这样称呼它:function(&array),对吧?
  • @Alek988Alek 好吧,首先请注意语法 char array[] { "abcd" }; 仅适用于 C++11,并且与 C 兼容的 char array[] = "abcd"; 做同样的事情,所以我建议使用 = 语法而不是{} 语法。其次,不,这不会造成破坏,因为空终止符是字符串文字的一部分,并且语言将复制它作为初始化的一部分。 (注意sizeof(array) == 5。)function(array) 很好,因为数组会自动衰减为指针类型。
【解决方案2】:

当我们离开这个函数时,array[] 被解除分配 - 对吧?

是的。像任何自动变量一样,它会在程序离开其范围时被销毁。

最后没有'\0'符号会导致堆损坏吗?

除非你写了一个超出范围的元素,否则它不会破坏任何东西;也许通过将它传递给像strcpy 这样的函数,它可以向它写入任意数量的字符。但是简单地创建它,在它的范围内写入,然后销毁它不会造成任何伤害。 (无论如何,它不太可能破坏堆,因为它在堆栈上)。

只有将数组内容解释为 C 风格字符串的代码才需要终止符。一般来说,数组不需要终止,在 C++ 中使用终止字符串是相当不寻常的,它有更方便的std::string 类型。

如果这样的功能经常出现怎么办?

没问题。每次都在函数的栈帧上创建数组,函数返回时释放。

如果我这样做是否一样:[new 没有delete]

这会导致内存泄漏,因为您正在分配一个动态数组但从未释放它。同样,它不会破坏任何东西,因为您只在数组范围内写入;但是如果你一直泄漏,那么最终你会耗尽内存。

【讨论】:

  • 有人打败了你,但无论如何,当然感谢! :)
猜你喜欢
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
  • 2011-06-06
  • 1970-01-01
  • 2010-11-15
  • 2016-07-31
相关资源
最近更新 更多