c-malloc()的异常行为

  • 本文关键字:异常 c-malloc 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("%sn", abc); //Prints abc
}

我预计strcpy会因为内存不足而失败,因为我将1传递给malloc()的参数。相反,它可以完美地编译和运行(在linux上的GCC和Windows上的dev c++中)。

这是意料之中的行为,还是一个愉快的巧合?

我认为这不是一个好的做法,但为什么它有效

如果没有malloc()末尾的+4,我会出现分段错误。这主要是我好奇的地方。

这是未定义的行为不要那样做

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

FWIW,

  • 在C标准中有一点值得注意,阻止访问越界(无效)内存和

  • strcpy()也不检查与源长度相比目的地缓冲器的大小

因此,这段代码(以某种方式)进行了编译。一旦你运行它,它就会到达UB,就再也不能保证什么了。

p.S-这里只有有保证的东西是未定义的行为

这基本上是对C中的指针是低级的并且(通常)未检查这一事实的另一个证明。你说你预计它会"因为没有足够的内存而失败",但想想看:你预计会失败什么?strcpy函数肯定不会检查它正在复制的字符串是否有足够的空间。它没有办法这样做;它得到的只是一个指针。它只是开始复制字符,在实践中,它要么成功,要么因违反分段而死亡。(但关键是它不会在"内存不足"时死亡。)

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

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

valgrind这样的工具肯定会检测到问题。

相关内容

  • 没有找到相关文章

最新更新