初始化数组时出现Seg Fault

时间:2010-09-28 17:04:23

标签: c for-loop segmentation-fault multidimensional-array

我正在上课,并遇到分段错误。根据我的理解,当您访问尚未分配的内存或超出边界时,应该发生seg错误。 “当然我要做的就是初始化一个数组(虽然相当大)

我只是误解了如何解析二维数组?错位一个边界正是导致seg错误的原因 - 我在使用嵌套for-loop时错了吗?

教授提供了时钟功能,所以我希望这不是问题所在。我在Cygwin中运行此代码,这可能是问题吗?源代码如下。也使用c99标准。

非常清楚:我正在寻求帮助理解(并最终修复)我的代码产生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;

}

6 个答案:

答案 0 :(得分:10)

您的程序在我的计算机上运行正常(x86-64 / Linux),所以我怀疑您遇到了系统特定的调用堆栈大小限制。我不知道你在Cygwin上有多少堆栈,但是你的数组是4,000,000字节(32位int) - 这可能很容易太大。

尝试将majorArray的声明移出main(将其放在#include之后) - 然后它将是一个全局变量,来自不同的分配池这可能会更大。

顺便说一句,这种比较是倒退的:

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

另外,要做这样的测试,你真的应该为许多不同的阵列尺寸和形状重复这个过程。

答案 1 :(得分:6)

您正尝试在堆栈上抓取1000 * 1000 * sizeof( int )个字节。这比您的操作系统允许堆栈增长更多。如果在任何Unix上 - 检查ulimit -a进程的最大堆栈大小。

根据经验,用malloc(3)在堆上分配大型结构。或者使用静态数组 - 超出任何函数的范围。

在这种情况下,您可以将majorArray的声明替换为:

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

答案 2 :(得分:3)

我无法在您的代码中找到任何错误,因此我编译并运行它并按预期工作。

但是,您的代码中存在语义错误:

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

应该是:

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

此外,最后的条件应改为反向:

if(rowMajor<colMajor)

最后,为了避免其他人提到的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;

答案 3 :(得分:1)

这个代码在Linux下运行正常,我看不出任何明显的错误。您可以尝试通过gdb进行调试。像这样编译:

gcc -g -o testcode test.c

然后说

gdb ./testcode

并在gdb中说run

如果它崩溃,请说where并且gdb告诉你崩溃发生的位置。然后你现在在错误的哪一行。

答案 4 :(得分:1)

该程序在由gcc和&amp;编译时完美运行。在Linux中运行,Cygwin可能就是你的问题。

答案 5 :(得分:0)

如果它在其他地方正确运行,你最有可能试图获得比操作系统允许的更多的堆栈空间。你在堆栈上分配4MB(1个整数),这对于在堆栈上“安全”分配来说太过分了。 malloc()和free()是你最好的选择。