关于malloc()的奇怪行为

时间:2016-04-19 19:48:37

标签: c malloc

为什么这样做?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{

    char * abc = malloc(1) + 4; //WRONG use of malloc.
    char * xyz = "abc";
    strcpy(abc, xyz); //Should fail.
    printf("%s\n", abc); //Prints abc
}

我希望strcpy因没有足够的内存而失败,因为我将1传递给malloc()的参数。相反,它可以完美地编译和运行(在Linux上的GCC和Windows上的dev c ++)。

这是预期的行为还是巧合?

我认为这不是一个好习惯,但为什么会有效?

如果+4末尾没有malloc(),我会遇到分段错误。这主要是我很好奇的。

3 个答案:

答案 0 :(得分:6)

这是undefined behavior不要那样做!!

您正尝试访问分配区域之外的内存位置。因此,内存位置无效,访问无效内存会调用UB。

FWIW,

  • 在C标准中注意到阻止您访问出界(无效)内存和

  • strcpy()检查目标缓冲区的大小与源长度相比

所以,这段代码(以某种方式)编译。一旦你运行它并且它击中UB,就不再保证任何东西了。

P.S - the only guaranteed thing here is undefined behavior.

答案 1 :(得分:5)

这基本上是C的指针是低级别且(通常)未被检查的事实的另一个证明。你说过你期望它没有足够的内存和#34;但是想一想:你期望失败的是什么? strcpy函数肯定不会检查它复制的字符串是否有足够的空间。它没有办法这样做;它得到的只是一个指针。它只是开始复制字符,实际上它会在分段违规时成功或死亡。 (但重点是死于&#34;内存不足&#34;。)

答案 2 :(得分:1)

不要依赖这种行为。回答“积极”的回答者是合理的,因为依赖这种行为可能潜伏多年未被发现,然后,有一天,对运行时系统的微小调整突然导致灾难性的失败。

它似乎有效,因为自从32位计算机出现以来,许多(如果不是大多数)C运行时库实现了malloc / free,它以16字节的粒度管理堆。也就是说,使用1到16之间的参数调用malloc()可提供相同的分配。所以你得到的内存比你要求的多一点,并且允许它执行。

valgrind这样的工具肯定会发现问题。