简体   繁体   English

初始化数组时出现Seg Fault

[英]Seg Fault when initializing array

I'm taking a class on C, and running into a segmentation fault. 我正在上课,并遇到分段错误。 From what I understand, seg faults are supposed to occur when you're accessing memory that hasn't been allocated, or otherwise outside the bounds. 根据我的理解,当您访问尚未分配的内存或超出边界时,应该发生seg错误。 'Course all I'm trying to do is initialize an array (though rather large at that) '当然我要做的就是初始化一个数组(虽然相当大)

Am I simply misunderstanding how to parse a 2d array? 我只是误解了如何解析二维数组? Misplacing a bound is exactly what would cause a seg fault-- am I wrong in using a nested for-loop for this? 错误放置绑定正是导致seg错误的原因 - 我在使用嵌套for-loop时错了吗?

The professor provided the clock functions, so I'm hoping that's not the problem. 教授提供了时钟功能,所以我希望这不是问题所在。 I'm running this code in Cygwin, could that be the problem? 我在Cygwin中运行此代码,这可能是问题吗? Source code follows. 源代码如下。 Using c99 standard as well. 也使用c99标准。

To be perfectly clear: I am looking for help understanding (and eventually fixing) the reason my code produces a seg fault. 要非常清楚:我正在寻找帮助理解(并最终修复)我的代码产生seg错误的原因。

#include <stdio.h>
#include <time.h>
int main(void){
   //first define the array and two doubles to count elapsed seconds.   
   double rowMajor, colMajor;
   rowMajor = colMajor = 0;
   int majorArray [1000][1000] = {};

   clock_t start, end;

   //set it up to perform the test 100 times.
   for(int k = 0; k<10; k++)
   {
   start=clock();
   //first we do row major
   for(int i = 0; i < 1000; i++)
   {
       for(int j = 0; j<1000; j++)
       {
           majorArray[i][j] = 314;
       }
   }
   end=clock();
   rowMajor+= (end-start)/(double)CLOCKS_PER_SEC;
   //at this point, we've only done rowMajor, so elapsed = rowMajor
   start=clock();
   //now we do column major
     for(int i = 0; i < 1000; i++)
   {
       for(int j = 0; j<1000; j++)
       {
           majorArray[j][i] = 314;
       }
   }
   end=clock();
   colMajor += (end-start)/(double)CLOCKS_PER_SEC;
   }
   //now that we've done the calculations 100 times, we can compare the values.
   printf("Row major took %f seconds\n", rowMajor);
   printf("Column major took %f seconds\n", colMajor);
   if(rowMajor<colMajor)
   {
     printf("Row major is faster\n");
   }
   else
   {
      printf("Column major is faster\n");
   }

   return 0;

}

Your program works correctly on my computer (x86-64/Linux) so I suspect you're running into a system-specific limit on the size of the call stack. 您的程序在我的计算机上运行正常(x86-64 / Linux),所以我怀疑您在调用堆栈的大小上遇到系统特定的限制。 I don't know how much stack you get on Cygwin, but your array is 4,000,000 bytes (with 32-bit int ) - that could easily be too big. 我不知道你在Cygwin上有多少堆栈,但你的数组是4,000,000字节(32位int ) - 这可能很容易。

Try moving the declaration of majorArray out of main (put it right after the #include s) -- then it will be a global variable, which comes from a different allocation pool that can be much bigger. 尝试将majorArray的声明移出main (在#include之后直接放置) - 然后它将是一个全局变量,它来自一个可以更大的不同分配池。

By the way, this comparison is backwards: 顺便说一句,这种比较是倒退的:

if(rowMajor>colMajor)
{
  printf("Row major is faster\n");
}
else
{
   printf("Column major is faster\n");
}

Also, to do a test like this you really ought to repeat the process for many different array sizes and shapes. 此外,要做这样的测试,你真的应该重复许多不同阵列大小和形状的过程。

You are trying to grab 1000 * 1000 * sizeof( int ) bytes on the stack. 您正试图在堆栈上获取1000 * 1000 * sizeof( int )字节。 This is more then your OS allows for the stack growth. 这比您的操作系统允许堆栈增长更多。 If on any Unix - check the ulimit -a for max stack size of the process. 如果在任何Unix上 - 检查ulimit -a以获取进程的最大堆栈大小。

As a rule of thumb - allocate big structures on the heap with malloc(3) . 根据经验 - 使用malloc(3)在堆上分配大型结构。 Or use static arrays - outside of scope of any function. 或者使用静态数组 - 超出任何函数的范围。

In this case, you can replace the declaration of majorArray with: 在这种情况下,您可以使用以下命令替换majorArray的声明:

int (*majorArray)[1000] = calloc(1000, sizeof majorArray);

I was unable to find any error in your code, so I compiled it and run it and worked as expected. 我无法在您的代码中找到任何错误,因此我编译并运行它并按预期工作。

You have, however, a semantic error in your code: 但是,您的代码中存在语义错误:

   start=clock();
   //set it up to perform the test 100 times.
   for(int k = 0; k<10; k++)
   {

Should be: 应该:

   //set it up to perform the test 100 times.
   for(int k = 0; k<10; k++)
   {
   start=clock();

Also, the condition at the end should be changed to its inverse: 此外,最后的条件应改为反向:

if(rowMajor<colMajor)

Finally, to avoid the problem of the os-specific stack size others mentioned, you should define your matrix outside main(): 最后,为了避免其他人提到的os特定堆栈大小的问题,你应该在main()之外定义你的矩阵:

#include <stdio.h>
#include <time.h>

int majorArray [1000][1000];

int main(void){
   //first define the array and two doubles to count elapsed seconds.   
   double rowMajor, colMajor;
   rowMajor = colMajor = 0;

This code runs fine for me under Linux and I can't see anything obviously wrong about it. 这个代码在Linux下运行正常,我看不出任何明显错误的东西。 You can try to debug it via gdb. 您可以尝试通过gdb进行调试。 Compile it like this: 像这样编译它:

gcc -g -o testcode test.c

and then say 然后说

gdb ./testcode

and in gdb say run 并在gdb中说run

If it crashes, say where and gdb tells you, where the crash occurred. 如果崩溃,说where和gdb告诉你,崩溃发生的位置。 Then you now in which line the error is. 然后你现在在错误的哪一行。

该程序在由gcc编译时运行良好,并且在Linux中运行,Cygwin可能就是你的问题。

If it runs correctly elsewhere, you're most likely trying to grab more stack space than the OS allows. 如果它在其他地方正确运行,你很可能试图获得比操作系统允许的更多的堆栈空间。 You're allocating 4MB on the stack (1 mill integers), which is way too much for allocating "safely" on the stack. 你在堆栈上分配4MB(1个整数),这对于在堆栈上“安全”分配来说太过分了。 malloc() and free() are your best bets here. malloc()和free()是你最好的选择。

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

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