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

fen*_*uxi 2 c malloc segmentation-fault

我使用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;
}
Run Code Online (Sandbox Code Playgroud)

chu*_*ica 5

int 溢出。

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

首先,让我们确定一个可能的分配大小计算

assert(SIZE__MAX/n/n/sizeof(float) >= 1);
Run Code Online (Sandbox Code Playgroud)

然后,通过足够宽的验证size_t,使用size_t数学进行乘法运算,并使用size_t数学进行数组索引计算。而不是int*int*size_tsize_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;
  }
}
Run Code Online (Sandbox Code Playgroud)

第2个循环未“失败”,n*n不是期望的大值,而是分配中的UB值相同。