使用一维数组的 C malloc 段错误

标签 c segmentation-fault malloc

我使用 malloc 在 C 中创建一个数组。但是当我尝试在 2 个循环中为数组分配随机值时出现段错误。

当我在 1 个循环中为这个数组赋值时,没有段错误。数组大小很大。请参阅我附上的代码。 任何人都可以给我提示这里发生了什么。我是 C 的新手。非常感谢。

int n=50000;
float *x = malloc(n*n*sizeof(float));

// there is segmentation fault:
int i, j;
for (i=0; i<n; i++){
   for (j=0; j<n; j++){
       x[i*n+j] = random() / (float)RAND_MAX;
    }
}
// there is no segmentation fault:
int ii;
for (ii=0; ii<n*n; ii++){
        x[ii] = random() / (float)RAND_MAX;
}

最佳答案

int 溢出。

50000 * 50000 --> 2,500,000,000 --> 超过 INT_MAX --> 未定义行为 (UB)。

首先,让我们确定可以计算此分配的大小

assert(SIZE__MAX/n/n/sizeof(float) >= 1);

然后在经过验证的size_t 足够宽的情况下,使用size_t 数学进行乘法运算,并使用size_t 数学进行数组索引计算。而不是 int*int*size_t,而是 size_t*int*int

// float *x = malloc(n*n*sizeof(float));

// Uses at least `size_t` math by leading the multiplication with that type.
float *x = malloc(sizeof(float) * n*n);
// or better
float *x = malloc(sizeof *x * n*n); 

for (i=0; i<n; i++){
  for (j=0; j<n; j++){
    x[(size_t)n*i + j] = random() / (float)RAND_MAX;
  }
}

第二个循环没有“失败”,因为 n*n 不是预期的大值,但可能与分配中的 UB 值相同。

关于使用一维数组的 C malloc 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55409794/

相关文章:

c++ - PVOID buffer转PCHAR有什么意义?

c - 程序内的终端行为

c - 创建窗口时出现 SDL 错误?

java - 线程中 SetDoubleArrayRegion 上的 JNI SIGSEGV

c++ - ofstream 关​​闭 C++ 中的段错误

c - 瓦尔格林德 C : Argument of function has a fishy (possibly negative) value

c - c中的for循环错误

c - 返回数组中找到的所有偶数

c - 如何在函数内初始化 Struct 指针数组?

C - scanf 无需直接访问即可更改数组的值