-2

我正在编写一个 C 代码来求解欧拉方程。我的代码在集群上工作得很好,但在我的电脑上却不行。似乎是 malloc() 的问题。它无法分配请求的内存并失败。

我如何使它工作?它与碎片整理有关吗?但系统设置显示(0% 碎片整理)。

仅在此处包含一部分 malloc() 代码。

double **u, **rho_u, **rho,    
int Size = 1000;
u = (double**)malloc(Size*sizeof(double*));
for(i=0;i<=Size;i++)
    u[i] = (double*)malloc(Size*sizeof(double));

rho_u = (double**)malloc(Size*sizeof(double*));
for(i=0;i<=Size;i++)
    rho_u[i] = (double*)malloc(Size*sizeof(double));
4

3 回答 3

5

你可能在这里破坏了你的堆:

for(i=0;i<=Size;i++)
    u[i] = (double*)malloc(Size*sizeof(double));

您分配了 1001 个指针,但只分配了 1000 个。正确版本:

for(i=0;i<Size;i++)
    u[i] = (double*)malloc(Size*sizeof(double));

第二个循环也一样。

于 2018-12-23T16:34:43.687 回答
4

仔细阅读. _ _ malloc可能会失败,并且当它失败时,会malloc返回NULL(并且失败的原因是errno您经常使用 显示的perror)。

因此,您应该针对malloc. 典型的代码至少是:

u = (double**)malloc(Size*sizeof(double*));
if (u==NULL) { perror ("malloc u"); exit(EXIT_FAILURE); };

同样为您rho_u和每个人rho_u[i]

某些操作系统可能会提供内存过度使用。这是我不喜欢的功能。

考虑完全初始化每个内存区域。并且在有效内存区域(或有效地址)之外使用内存是未定义的行为(并且您的程序有一个,由Ctx 的回答注意到)。害怕。_

我还建议使用valgrind。这是一个非常方便的工具来寻找与内存相关的错误,并且可以检测到你的错误。

于 2018-12-23T16:33:34.390 回答
2

观察:

  • 避免类型转换 malloc(),阅读我是否转换了 malloc 的结果?
  • 检查 & 的返回值malloc()并进行正确的错误处理。
  • 将循环条件从 更改i<=Size为 ,i<Size因为它会导致缓冲区溢出,因为早期的内存只分配给Size行而不是size+1行。

试试这个版本:

int Size = 1000;
double **u = malloc(Size * sizeof(*u)); /* typecasting is not needed */
if(u == NULL) {
   /* @TODO error handling */
}
for(i=0;i<Size;i++) { /* loop should rotate only 1000 times not 1001 times */
    u[i] = malloc(Size * sizeof(**u));
    if(u[i] == NULL) {
         /* @TODO error handling */
    }
}

同样对于rho_urho

于 2018-12-23T16:43:49.827 回答