简体   繁体   English

打印指针值的分段错误

[英]Segmentation fault on printing pointer value

The following program crashes when I try to print the value of v . 当我尝试打印v的值时,以下程序崩溃。 I'm trying to understand why. 我想知道为什么。 Any suggestions? 有什么建议么?

#include <stdio.h>

int main() {

    int v[5000000];
    printf("\n\nv = %p", v);
     return 0;
}

EDIT : the program does not segfault if instead of allocating 5000000 elements I allocate 500000 or less. 编辑 :如果不分配5000000个元素而不分配500000或更少,程序不会出现段错误。

EDIT(2) : increasing the stack size solved the problem. 编辑(2) :增加堆栈大小解决了问题。 On Linux, I increase the stack size after reading the answer of stephane-rouberol (using ulimit -s <some_large_number> ). 在Linux上,我在阅读了stephane-rouberol的答案后增加了堆栈大小(使用ulimit -s <some_large_number> )。

Congrats, you have stack overflow :) 恭喜,你有堆栈溢出 :)

Find a way to increase the size of the stack or just allocate the array dynamically: 找到一种方法来增加堆栈的大小或只是动态分配数组:

int* v = malloc( 5000000 * sizeof *v);

/* do something */

free( v );

Stack overflow ! 堆栈溢出 ! See ulimit -s if you use bash or limit stacksize if [t]csh 如果你使用bash或者如果[t]csh limit stacksize请参阅ulimit -s

Or instead of using stack, you can use the heap with malloc 或者不使用堆栈,您可以将堆与malloc

You already have the cause. 你已经有了原因。 5000000 is too big to handle for the program stack where v will be allocated. 对于将分配v的程序堆栈, 5000000太大而无法处理。 You should allocate it dynamically with malloc . 你应该用malloc动态分配它。

The stack size of a program is dependent on compiler switches and defaults are different from OS to OS. 程序的堆栈大小取决于编译器开关,默认值不同于OS到OS。 In your case it sounds as if the stack is too small to accomodate that large number. 在你的情况下,它听起来好像堆栈太小,无法容纳那么大的数字。 See your compiler(linker) switches to increase stack size. 请参阅编译器(链接器)开关以增加堆栈大小。

尝试

printf("\n\nv = %p", (void *)v);

As others have said, stack overflow. 正如其他人所说,堆栈溢出。 To understand why and when the code actually crashes, this is what goes on between the lines: 要了解代码实际崩溃的原因和时间,这就是行之间的事情:

  • Try to allocate 5000000 * sizeof(int) on the stack. 尝试在堆栈上分配5000000 * sizeof(int)。 Let's assume this is 20MB. 我们假设这是20MB。
  • The compiler (as opposed to the linker) most likely doesn't know how large the stack is, so it merrily assumes that 20MB of the stack are taken. 编译器(与链接器相对)很可能不知道堆栈有多大,所以它很乐意假设堆栈有20MB。
  • When calling printf(), the pointer address is passed on the stack to the function. 调用printf()时,指针地址在堆栈上传递给函数。 The compiler will try to push this pointer address (4 bytes) at stack location 0 + 20000004. This is outside valid memory and here the program will crash. 编译器将尝试在堆栈位置0 + 20000004处推送此指针地址(4个字节)。这是在有效内存之外,此处程序将崩溃。
  • Had the compiler used another calling convention for printf(), for example by passing the pointer address in a CPU register instead, the program wouldn't have crashed, not until you actually tried to read/write from that huge array. 如果编译器使用另一个printf()调用约定,例如通过将指针地址传递给CPU寄存器,程序就不会崩溃,直到你真正尝试从那个巨大的数组中读/写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM