2017-01-09 22 views
-2

有时,如果在C代码中访问数组超出范围,您将不会收到运行时错误。如:C数组段错误

char array[1024]; 
char* ptr = array; 
*(ptr-10) = 'a'; 

//or 

*(ptr-4096) = 'a'; 

假设array是在栈上,我很好奇什么是MIN SIZE,将让*(ptr-SIZE) = 'a'扔分割故障在任何情况下?

例如:

*(ptr-4096*1024) = 'a' // this will always throw a segmentation fault 
*(ptr-4096*8) = 'a' // sometimes this will not throw a segmentation fault 

2017年1月10日,新加的:

我感到抱歉,没有明确说明这个问题。 (

我想知道是不是只是一个模糊的UNDEFINED假设堆高,堆是低,所以在内存布局将是:。

high ********* 
    * stack * <- my array goes here 
    ********* 
    *  * 
    *  * <- ptr may be here 
    *  * 
    ********* 
    * heap * 
    ********* 
    * ??? * <- ptr may be here 
    ********* 

当然,我知道,

的问题是,C/C++实际上并没有做任何边界与问候阵列检查,这取决于操作系统,以确保您正在访问有效的内存

所以,上面的代码会引起操作系统内核调用do_page_fault,并会尝试找到vma的地址,并检查是否为vma->vm_start < address

现在,让我们回过头来,我问的问题:MIN SIZE,将让*(ptr-SIZE) = 'a'扔分割故障在任何情况下。换句话说,我想知道do_page_fault可以承受的SIZE。这与C编译器无关,而是您的操作系统如何保护您的内存。

+5

访问数组越界是[未定义的行为](http://en.cppreference.com/w/cpp/language/ub) – George

+0

像“未定义的行为”中的“未定义”这个词不清楚吗?你在哪里听到/阅读/ ..有这样的访问要求产生任何特定的行为? – Olaf

+0

你最好重新提出这个问题,作为一个操作系统问题,“用户空间过程必须做什么才能触发分段错误?”而不是长久以来似乎是一个新手C编程问题的答案。 – TrentP

回答

4

A C符合标准的编译器有权做任何事权利,如果你指数array[i]其中i小于0或大于1023

行为在这种情况下被说成是不确定

试图猜测会发生什么是徒劳的。但是如果你好奇,你总是可以检查生成的程序集。

+2

请注意,OP的问题中的引用是指针运算的结果,在这种情况下,它允许将指针指向“ptr + 1024”,而不是指向“ptr-1”。 '*(ptr + 1024)'当然是UB。 –