为什么这样做?
#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()
,我会遇到分段错误。这主要是我很好奇的。
答案 0 :(得分:6)
这是undefined behavior。 不要那样做!! 。
您正尝试访问分配区域之外的内存位置。因此,内存位置无效,访问无效内存会调用UB。
FWIW,
在C标准中注意到阻止您访问出界(无效)内存和
strcpy()
检查目标缓冲区的大小与源长度相比
所以,这段代码(以某种方式)编译。一旦你运行它并且它击中UB,就不再保证任何东西了。
答案 1 :(得分:5)
这基本上是C的指针是低级别且(通常)未被检查的事实的另一个证明。你说过你期望它没有足够的内存和#34;但是想一想:你期望失败的是什么? strcpy
函数肯定不会检查它复制的字符串是否有足够的空间。它没有办法这样做;它得到的只是一个指针。它只是开始复制字符,实际上它会在分段违规时成功或死亡。 (但重点是不死于&#34;内存不足&#34;。)
答案 2 :(得分:1)
不要依赖这种行为。回答“积极”的回答者是合理的,因为依赖这种行为可能潜伏多年未被发现,然后,有一天,对运行时系统的微小调整突然导致灾难性的失败。
它似乎有效,因为自从32位计算机出现以来,许多(如果不是大多数)C运行时库实现了malloc / free,它以16字节的粒度管理堆。也就是说,使用1到16之间的参数调用malloc()
可提供相同的分配。所以你得到的内存比你要求的多一点,并且允许它执行。
像valgrind
这样的工具肯定会发现问题。