为什么我可以设置一个大于我使用malloc()保留的字符数组?

时间:2013-03-12 18:58:48

标签: c string memory dynamic

为什么打印出“test”?:

    char *str;
    str = (char *)malloc(1);
    str[0] = 't';
    str[1] = 'e';
    str[2] = 's';
    str[3] = 't';

我正在尝试动态扩展字符串并尝试理解malloc / realloc是如何工作的,上面的行为让我感到困惑,因为malloc()/ realloc()建议扩展char *。

提前致谢。

3 个答案:

答案 0 :(得分:4)

未定义的行为意味着任何事情都可能发生。包括出现“工作”,什么都没有,或者是分段错误。您的示例代码确实很糟糕,但C标准并不保证它会做任何“有用”的事情,也不保证在编译时或运行时都会发生任何“坏”。

答案 1 :(得分:2)

您正在撰写超出“正式”分配内存的末尾。大多数内存分配系统都具有内部使用的最小大小,并且您可能实际上并未超出那个边界,因此您的代码似乎正在运行。如果你让字符串足够长,你最终会传递一个对操作系统很重要的边界,你的程序就会崩溃。

您可以为str分配一个随机数,然后将其视为指针,并且每隔一段时间它就会真正起作用。但你不知道你可能会写什么。与你的记忆超限相同。内存分配器可以紧密地打包分配,以便您覆盖程序中的其他内容。

你应该总是确保你不会超出任何数组的范围。的 EVER 即可。缓冲区溢出(和欠载)正是许多黑客利用它们进入系统的原因。确保你不允许它们,并且你已经在那里有相当多的旧代码了。

答案 2 :(得分:1)

这段代码显然是错误的 - 很明显 - 你正在通过数组边界访问内存。

它有效,因为:

  • 没有机制来检测每个无效的内存访问。许多这样的尝试会导致分段错误,但每次都不会发生。很多时候这样的错误代码只是覆盖了一些随机变量等等 - 这就是为什么像这样的调试问题很快就会成为一场噩梦的原因之一。我建议你熟悉Valgrind

  • 在这种特殊情况下,我会说malloc()将分配的内存块四舍五入到(至少)4的倍数,所以在这种情况下它可能会按预期工作。但它仍然是一个错误。

  • 你也没有明确地终止字符串,而且 - 行为实际上是随机的,str[4]可以有任何价值。它取决于很多东西 - 从堆分配器实现到纯巧合。