2012-01-01 137 views
4

可能重复:
Invalid read/write sometimes creates segmentation fault and sometimes does not为什么运行这不会产生分段错误?

我有以下代码:

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

int main() { 
    int *ptr = NULL; 
    ptr = malloc(sizeof(char)); 
    if (ptr) { 
     *ptr = 10; 
     printf("sizeof(int): %zu\nsizeof(char): %zu\n", sizeof(int), sizeof(char)); 
     printf("deref of ptr: %d\n", *ptr); 
     free(ptr); 
     return EXIT_SUCCESS; 
    } 
    else 
     return EXIT_FAILURE; 
} 

当我编译并运行它,我得到以下输出:

$ gcc test.c 
$ ./a.out 
sizeof(int): 4 
sizeof(char): 1 
deref of ptr: 10 

sizeof(char)小于sizeof(int)。我的malloc呼叫只留出足够的空间用于char。但是,我的程序能够在不崩溃的情况下为ptr分配一个整数值。为什么这个工作?

+1

你可能想看看这个问题及其答案的指导:http://stackoverflow.com/questions/8641478/invalid-read -write-sometimes-creating-segmentation-fault-and-sometimes-does-not – 2012-01-01 21:58:16

+0

C不一定会遵守变量'boundries',所以你可能会覆盖内存中的一些随机3字节, 。 – 2012-01-01 22:01:29

+0

'sizeof(char)'总是1(6.5.3.4,§3)。 – 2012-01-01 22:04:41

回答

8

仅仅因为你正在写未分配的内存并不意味着程序会崩溃。没有像那样的运行时间边界检查。由硬件检测到时要访问存储器出通过操作系统分配的地址范围将发生

的段错误。你可能会在堆之前获得大量的内存访问权限。

4

malloc实现可以,而且往往会分配多一点内存比你所要求的。大多数实现将最小化为8或16个字节的最接近倍数。

6

写入太小的缓冲区是未定义的行为。没有保证它会崩溃。它可能不会崩溃。它可能似乎工作。它也可能会悄悄地破坏一些数据。这可能会导致程序做一些意想不到的事情 - 当攻击者将未定义行为的影响转化为不希望的事情时,会出现很多安全漏洞。通过严格阅读标准,这甚至可能会从你的鼻子召唤恶魔。

在架构层面,通常分配四舍五入到2的某次幂(但不以任何方式保证!),因此为什么你没有看到任何明显的不良这里。但不依赖于此,因为它可以并且确实有所不同。

1

这工作意外。你的malloc可能会分配一个大于单个字符的块(通常是因为跟踪纳米片不值得花费)。所以你很可能在你应该拥有的空间之外跑来跑去,但是在你的实现中并不重要。

你的程序仍然是错误的,我认为,根据标准。而且,如果它更大,并且你在无意中发生意外的地方犯了这个错误,你会得到各种不良行为,有时是非法的内存访问,但有时候只是完全疯狂的行为,因为你可能会损坏你的或系统数据结构。

我们CheckPointer测试工具应该能够发现这个错误;从技术上讲,您要存储在您请求的区域之外,并且可以通过足够的努力进行检测。

2

硬件的内存管理器控制完整的内存页,往往4K。除非写入溢出页边界,否则内存管理硬件不会生成SEGFAULT/Access Violation中断。

你的例子'工作',因为'未定义行为'的大集合中的一个元素'看起来工作正常,至少现在'。如果你的应用程序增加了复杂性,该集的其他成员将出现...

相关问题