1

当我尝试在 gcc 上编译此代码时出现分段错误错误。

#include <stdio.h>
#include <stdlib.h>

#define N_TIMES     600000
#define ARRAY_SIZE   10000

int main (void)
{
    double  *array = calloc(ARRAY_SIZE, sizeof(double));
    double  sum = 0;
    int     i;

    double sum1 = 0;


    for (i = 0; i < N_TIMES; i++) {

        int     j;

        for (j = 0; j < ARRAY_SIZE; j += 20) {
            sum += array[j] + array[j+1] + array[j+2] + array[j+3] + array[j+4] + array[j+5] + array[j+6] + array[j+7] + array[j+8] + array[j+9];
            sum += array[j+10] + array[j+11] + array[j+12] + array[j+13] + array[j+14] + array[j+15] + array[j+16] + array[j+17] + array[j+18] + array[j+19];
            }
        }

    sum += sum1;

    return 0;
}

我正在尝试尽可能多地加快 for 循环,所以我正在尝试疯狂的事情。如何摆脱分段错误?我还应该尝试不同的优化方法吗?

4

2 回答 2

2
  1. 编译器几乎肯定会比你优化得更好。不要试图超越编译器。

  2. 问题几乎可以肯定是sum += array[ARRAY_SIZE];C 中的数组索引从 0 变为 size-1,所以在这里你可能会“结束”

于 2013-08-20T00:34:17.697 回答
1

所以你最初的问题是由于你在内部循环中使用i而不是j在你的数组索引中使用,并且因为N_TIMES它比ARRAY_SIZE你最终会溢出你的数组边界要大得多,这是未定义的行为。

改正后的代码还有一个明显的问题:

sum += array[ARRAY_SIZE];

的有效索引array将来自0 to ARRAY_SIZE-1因此访问元素ARRAY_SIZE通过超出数组边界来调用未定义的行为。

于 2013-08-20T01:02:12.317 回答