c语言 - 这个 malloc 不应该工作



这是我的代码。

 int     main()
  {
  char *s;
  int i = 0;
  printf("%lu n", sizeof(s));
  s = malloc(sizeof(char) * 2);
  printf("%lu n", sizeof(s));
  /*Why is this working?*/
  while (i <= 5)
    {
      s[i] = 'l';
      i++;
    }
  printf("%s n", s);
  printf("%lu n", sizeof(char));
  printf("%lu n", sizeof(s[0]));
  }

我认为,这应该是我试图比分配更多的写作时要记住的。为什么工作?

我认为,这应该是我试图比分配更多的写作时要记住的。为什么这可以工作?

这不是"工作";您的代码调用不确定的行为。"未定义的行为"并不意味着"您的代码将segfault segfault"。那将是定义的行为。UB意味着任何事情都可能发生。

在这种情况下,您正在踩在不拥有的内存上。这有时会遇到segfault,但不要指望它。C没有" segfaults"的概念,来自您的操作系统。

segfault是从操作系统的 signal 告诉您,访问特定的存储区与您的业务无关。碰巧的是,您要访问的内容不会触发OS的内存管理单元中的警报。有很多方法可以利用(覆盖函数调用,通过覆盖堆栈值对二进制的攻击等)。

)。

也可能是您的Malloc不仅分配这两个字节和2个字节。Malloc调用一个系统调用,该系统调用虚拟内存页面(可能大于2个字节)。该SYSCALL(分别用于Linux和Windows的sbrkVirtualAlloc)告诉OS将这些页面映射到您需要的内容上,然后保护它们,以使其没有其他任何人(读:读:另一个过程/应用程序)在您的存储区域上意外踩踏那个情况下,操作系统会用segfault击中一个人的头)。

还有其他提到的不确定的行为。

在插图中与附加变量的少量添加的代码以完全相同的方式声明,并在char *s之后立即使用malloc'ed。

尽管不保证 将变量顺序存储在内存中,以这种方式创建它们使其很高的可能性。如果是这样char *t现在将拥有char *s将侵占的空间,而您 Will 获得SEG故障:

int     main()
{
    char *s;
    char *t;//addition
    int i = 0;
    printf("%lu n", sizeof(s));
    s = malloc(sizeof(char) * 2);
    t = malloc(sizeof(char) * 2);//addition
    printf("%lu n", sizeof(s));
    /*Why is this working?*/
    while (i <= 5)
    {
      s[i] = 'l';
      i++;
    }
    printf("%s n", s);
    printf("%lu n", sizeof(char));
    printf("%lu n", sizeof(s[0]));
}

注意: 在我使用的环境中(Windows 7,Ni运行时,调试等),我以任何一种支持其他答案中的未定义行为断言。

似乎是这样的:malloc分配了一些字节,多于您指定的。

使用malloc(sizeof(s)*2);//8然后(i&lt; = 36)还可以,但是(i&lt; = 37)已经不是..

使用例如malloc(sizeof(s)*4);//16然后(i&lt; = 7572)还可以,但是(i&lt; = 7573)已经不是..

(我在Code :: Blocks中进行了测试)

太糟糕了,丹尼斯·里奇(Dennis Ritchie)死了,这仍然是一个大谜那,但是只是不必太担心它总是足够分配您需要,无效终止字符串

正如其他人所说的那样,它的命中率或错过了代码是在生产中导致运行时错误,因为界限检查未内置在C 中(与语言不同,Java或C#)。该代码将在内存检查器下引起错误。

您可能知道Valgrind,所以这是读者的练习。这是Clang的地址消毒剂(我添加了一个printf("malloc: %p n", s);)的情况:

$ ./t.exe | /usr/local/bin/asan_symbolize.py 
malloc: 0x60200000b3b0 
=================================================================
==98557==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000b3b2 at pc 0x1065c4b5b bp 0x7fff5963b810 sp 0x7fff5963b808
WRITE of size 1 at 0x60200000b3b2 thread T0
    #0 0x1065c4b5a (/Users/jwalton/./t.exe+0x100000b5a)
    #1 0x7fff870e27e0 (/usr/lib/system/libdyld.dylib+0x27e0)
    #2 0x0
0x60200000b3b2 is located 0 bytes to the right of 2-byte region [0x60200000b3b0,0x60200000b3b2)
allocated by thread T0 here:
    #0 0x1065d8cd5 (/usr/local/lib/clang/3.3/lib/darwin//libclang_rt.asan_osx_dynamic.dylib+0xfcd5)
    #1 0x1065c4971 (/Users/jwalton/./t.exe+0x100000971)
    #2 0x7fff870e27e0 (/usr/lib/system/libdyld.dylib+0x27e0)
    #3 0x0
Shadow bytes around the buggy address:
  0x1c0400001620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400001630: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400001640: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400001650: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400001660: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x1c0400001670: fa fa fa fa fa fa[02]fa fa fa 00 00 fa fa fd fa
  0x1c0400001680: fa fa fd fa fa fa 00 00 fa fa fd fa fa fa fd fa
  0x1c0400001690: fa fa 00 00 fa fa 00 00 fa fa fd fa fa fa fd fa
  0x1c04000016a0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x1c04000016b0: fa fa 00 00 fa fa fd fa fa fa fd fa fa fa 00 00
  0x1c04000016c0: fa fa 00 00 fa fa fd fa fa fa fd fa fa fa 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap right redzone:    fb
  Freed heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==98557==ABORTING

相关内容

  • 没有找到相关文章

最新更新