C 打印指针值时的分段错误

C 打印指针值时的分段错误,c,C,当我试图打印v的值时,以下程序崩溃。我想知道为什么。有什么建议吗 #include <stdio.h> int main() { int v[5000000]; printf("\n\nv = %p", v); return 0; } #包括 int main(){ 国际价值[5000000]; printf(“\n\nv=%p”,v); 返回0; } 编辑:如果不是分配5000000个元素,而是分配500000个或更少的元素,则程序不会出错 编辑(

当我试图打印
v
的值时,以下程序崩溃。我想知道为什么。有什么建议吗

#include <stdio.h>

int main() {

    int v[5000000];
    printf("\n\nv = %p", v);
     return 0;
}
#包括
int main(){
国际价值[5000000];
printf(“\n\nv=%p”,v);
返回0;
}
编辑:如果不是分配5000000个元素,而是分配500000个或更少的元素,则程序不会出错

编辑(2):增加堆栈大小解决了问题。在Linux上,我在阅读stephane rouberol的答案后增加了堆栈大小(使用
ulimit-s
)。

恭喜,堆栈溢出:)

找到一种增加堆栈大小的方法,或者只动态分配阵列:

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

/* do something */

free( v );

你已经有了原因
5000000
太大,无法处理将分配
v
的程序堆栈。您应该使用
malloc
动态地分配它。程序的堆栈大小取决于编译器开关,不同操作系统的默认值不同。在您的情况下,听起来好像堆栈太小,无法容纳这么大的数字。查看编译器(链接器)开关以增加堆栈大小。

试试看

printf("\n\nv = %p", (void *)v);
堆栈溢出! 如果使用
bash
limitstacksize
如果
[t]csh


或者,您可以将堆与
malloc

一起使用,而不是使用堆栈,正如其他人所说,堆栈溢出。为了理解代码实际崩溃的原因和时间,以下是行与行之间发生的情况:

  • 尝试在堆栈上分配5000000*sizeof(int)。让我们假设这是20MB
  • 编译器(与链接器相反)很可能不知道堆栈有多大,因此它愉快地假设堆栈的大小为20MB
  • 调用printf()时,指针地址在堆栈上传递给函数。编译器将尝试将此指针地址(4字节)推送到堆栈位置0+2000004。这超出了有效内存,程序将在此崩溃
  • 如果编译器对printf()使用了另一种调用约定,例如通过在CPU寄存器中传递指针地址,程序就不会崩溃,直到您真正尝试从这个巨大的数组读/写

那么堆栈上存储了一个数组
v[10000]
?但是为什么程序会在打印阶段崩溃呢?另外,如何增加堆栈大小?@curvature-这取决于编译器。您应该阅读它的手册。@Als-不是
%p
的意思-打印地址,而不是所指的内容?此外,他似乎有一个相当糟糕的编译器/链接器,不知道目标平台进程的堆栈有多大。我希望链接器至少在桌面操作系统编译器上知道这一点。例如,在Windows中,我相信您可以通过一个简单的API调用GetSystemInfo()来获取此信息。@Lundin:最大堆栈大小可以由用户更改(请参阅我在文章中的第二次编辑),因此我对编译器并不感到惊讶(
gcc
)不知道正在编译的程序允许的最大堆栈大小。为什么要打印未初始化数组的“不确定”元素?我正在打印指针值。
v
不是指向
int
s数组的指针吗?那不起作用。程序以相同的方式分段故障(从其他答案可以看出)。