如何修复堆栈溢出错误?
how to fix stack overflow error?
所以,我正在制作这个程序,让人们知道总和等于某个值的连续子数组的数量。
我已经编写了代码,但是当我尝试在 vcexpress 2010 中 运行 这段代码时,它说这些错误
Unhandled exception at 0x010018e7 in test 9.exe: 0xC00000FD: Stack overflow.
我试图在本网站和其他网站上搜索解决方案,但我似乎找不到任何可以帮助我修复此代码中的错误的解决方案(他们正在使用递归,而我没有).
如果您能解释一下导致我的代码出现此错误的原因以及如何修复此错误,我将不胜感激。任何帮助,将不胜感激。谢谢。
这是我的代码:
#include <stdio.h>
int main ()
{
int n,k,a=0,t=0;
unsigned long int i[1000000];
int v1,v2=0,v3;
scanf("%d %d",&n,&k);
for(v3=0;v3<n;v3++)
{
scanf("%d",&i[v3]);
}
do
{
for(v1=v2;v1<n;v1++)
{
t=i[v1]+t;
if(t==k)
{
a++;
break;
}
}
t=0;
v2++;
}while(v2!=n);
printf("%lu",a);
return 0;
}
或者移动
unsigned long int i[1000000];
在 main
之外,从而使其成为全局变量(不是 automatic one), or better yet, use some C dynamic heap allocation:
// inside main
unsigned long int *i = calloc(1000000, sizeof(unsigned long int));
if (!i) { perror("calloc"); exit(EXIT_FAILURE); };
顺便说一句,对于这样的指针,我会使用(出于可读性原因)不同于 i
的其他名称。在 main
接近尾声时,您最好 free(i);
避免 memory leaks.
此外,您可以在读取 n
后移动这两行,并使用 calloc(n, sizeof(unsigned long int))
而不是 calloc(1000000, sizeof(unsigned long int))
;如果您的计算机和系统提供足够的资源,那么您可以处理大于一百万个元素的数组。
您的初始代码正在声明一个自动变量,该变量进入 call stack (which has a limited size, typically a megabyte or a few of them). On some operating systems there is a way to increase the size of that call stack (in an OS-specific way). BTW each thread 上的 main
的调用框架,它有自己的调用堆栈。
根据经验,您的 C 函数(包括 main
)应避免调用帧大于几千字节。使用 GCC compiler, you could invoke it with gcc -Wall -Wextra -Wframe-larger-than=1024 -g
获取有用的警告和调试信息。
阅读virtual address space wikipage. It has a nice picture worth many words. Later, find the way to query, on your operating system, the virtual address space of your process (on Linux, use proc(5) like cat /proc/$$/maps
etc...). In practice, your virtual address space is likely to contain many segments (perhaps a dozen, sometimes thousands). Often, the dynamic linker or some other part of your program (or of your C standard library) uses memory-mapped files. The standard C heap (managed by malloc
etc) may be organized in several segments。
如果您想了解有关虚拟地址的更多信息 space,请花时间阅读一本好书,例如:Operating systems, three easy pieces(可免费下载)。
如果你想从进程内部查询某些process, you need to find an operating-system specific way to do that (on Linux, for a process of pid 1234, use/proc/1234/maps
或/proc/self/maps
的虚拟地址space的组织。
内存的布局与简单的 4 段(很久以前完成的)有很大不同。问题的答案可以这样概括——global or dynamically allocated memory space 的处理方式不同于 local variables by the system, local variables memory is limited in size, memory for dynamic allocation or global variables doesn't put a lower constraint like this.
在现代系统中存在虚拟地址space的概念。您程序中的进程获得了其中的一部分。那部分内存现在负责保存所需的内存。
现在对于动态分配等,进程可以请求更多内存,并且根据其他进程等,为新的内存请求提供服务。对于动态或全局数组,在进程方面没有限制(当然在系统方面有-它不能请求所有内存)。这就是为什么动态分配或使用全局变量不会导致进程 运行 超出其分配的内存,这与它最初为局部变量提供的自动生命周期内存不同。
基本上你可以检查你的筹码量
例如在 Linux 中:ulimit -s (Kbytes)
然后决定你如何操作你的代码。
作为一个概念,我永远不会在堆栈上分配大块内存,因为除非您确切知道函数调用的深度和堆栈使用,否则很难在 运行 时间 [=10] 期间控制堆栈上精确分配的内存=]
所以,我正在制作这个程序,让人们知道总和等于某个值的连续子数组的数量。
我已经编写了代码,但是当我尝试在 vcexpress 2010 中 运行 这段代码时,它说这些错误
Unhandled exception at 0x010018e7 in test 9.exe: 0xC00000FD: Stack overflow.
我试图在本网站和其他网站上搜索解决方案,但我似乎找不到任何可以帮助我修复此代码中的错误的解决方案(他们正在使用递归,而我没有).
如果您能解释一下导致我的代码出现此错误的原因以及如何修复此错误,我将不胜感激。任何帮助,将不胜感激。谢谢。
这是我的代码:
#include <stdio.h>
int main ()
{
int n,k,a=0,t=0;
unsigned long int i[1000000];
int v1,v2=0,v3;
scanf("%d %d",&n,&k);
for(v3=0;v3<n;v3++)
{
scanf("%d",&i[v3]);
}
do
{
for(v1=v2;v1<n;v1++)
{
t=i[v1]+t;
if(t==k)
{
a++;
break;
}
}
t=0;
v2++;
}while(v2!=n);
printf("%lu",a);
return 0;
}
或者移动
unsigned long int i[1000000];
在 main
之外,从而使其成为全局变量(不是 automatic one), or better yet, use some C dynamic heap allocation:
// inside main
unsigned long int *i = calloc(1000000, sizeof(unsigned long int));
if (!i) { perror("calloc"); exit(EXIT_FAILURE); };
顺便说一句,对于这样的指针,我会使用(出于可读性原因)不同于 i
的其他名称。在 main
接近尾声时,您最好 free(i);
避免 memory leaks.
此外,您可以在读取 n
后移动这两行,并使用 calloc(n, sizeof(unsigned long int))
而不是 calloc(1000000, sizeof(unsigned long int))
;如果您的计算机和系统提供足够的资源,那么您可以处理大于一百万个元素的数组。
您的初始代码正在声明一个自动变量,该变量进入 call stack (which has a limited size, typically a megabyte or a few of them). On some operating systems there is a way to increase the size of that call stack (in an OS-specific way). BTW each thread 上的 main
的调用框架,它有自己的调用堆栈。
根据经验,您的 C 函数(包括 main
)应避免调用帧大于几千字节。使用 GCC compiler, you could invoke it with gcc -Wall -Wextra -Wframe-larger-than=1024 -g
获取有用的警告和调试信息。
阅读virtual address space wikipage. It has a nice picture worth many words. Later, find the way to query, on your operating system, the virtual address space of your process (on Linux, use proc(5) like cat /proc/$$/maps
etc...). In practice, your virtual address space is likely to contain many segments (perhaps a dozen, sometimes thousands). Often, the dynamic linker or some other part of your program (or of your C standard library) uses memory-mapped files. The standard C heap (managed by malloc
etc) may be organized in several segments。
如果您想了解有关虚拟地址的更多信息 space,请花时间阅读一本好书,例如:Operating systems, three easy pieces(可免费下载)。
如果你想从进程内部查询某些process, you need to find an operating-system specific way to do that (on Linux, for a process of pid 1234, use/proc/1234/maps
或/proc/self/maps
的虚拟地址space的组织。
内存的布局与简单的 4 段(很久以前完成的)有很大不同。问题的答案可以这样概括——global or dynamically allocated memory space 的处理方式不同于 local variables by the system, local variables memory is limited in size, memory for dynamic allocation or global variables doesn't put a lower constraint like this.
在现代系统中存在虚拟地址space的概念。您程序中的进程获得了其中的一部分。那部分内存现在负责保存所需的内存。
现在对于动态分配等,进程可以请求更多内存,并且根据其他进程等,为新的内存请求提供服务。对于动态或全局数组,在进程方面没有限制(当然在系统方面有-它不能请求所有内存)。这就是为什么动态分配或使用全局变量不会导致进程 运行 超出其分配的内存,这与它最初为局部变量提供的自动生命周期内存不同。
基本上你可以检查你的筹码量 例如在 Linux 中:ulimit -s (Kbytes) 然后决定你如何操作你的代码。 作为一个概念,我永远不会在堆栈上分配大块内存,因为除非您确切知道函数调用的深度和堆栈使用,否则很难在 运行 时间 [=10] 期间控制堆栈上精确分配的内存=]