malloc 分配内存失败
malloc is failing to allocate memory
我正在编写 C 代码来求解欧拉方程。我的代码在集群上工作得很好,但在我的电脑上却不行。似乎是 malloc() 的问题。它无法分配请求的内存并失败。
我如何让它发挥作用?与碎片整理有关吗?但是系统设置显示 (0% Defragmented).
这里只包括一部分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));
仔细阅读 documentation of malloc
. It can fail, and when it does fail, malloc
returns NULL
(and the failure reason is given by errno
which you often display using perror
).
所以你应该针对 malloc
的失败进行测试。典型代码至少为:
u = (double**)malloc(Size*sizeof(double*));
if (u==NULL) { perror ("malloc u"); exit(EXIT_FAILURE); };
同样适用于您的 rho_u
和每个 rho_u[i]
一些操作系统可能提供 memory overcomitment。这是我不喜欢的功能。
考虑完全初始化每个内存区域。在有效内存区域(或有效地址)之外使用内存是 undefined behavior (and your program have one, noticed by ). Be .
我也推荐使用 valgrind。这是一个非常方便的工具,可以用来寻找与内存相关的错误,并且可以检测到您的错误。
您可能在此处损坏了您的堆:
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));
第二个循环相同。
观察:
- 避免类型转换
malloc()
,阅读 Do I cast the result of malloc?
- 检查
malloc()
的 return 值并进行正确的错误处理。
- 将循环条件从
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_u
和 rho
类似。
我正在编写 C 代码来求解欧拉方程。我的代码在集群上工作得很好,但在我的电脑上却不行。似乎是 malloc() 的问题。它无法分配请求的内存并失败。
我如何让它发挥作用?与碎片整理有关吗?但是系统设置显示 (0% Defragmented).
这里只包括一部分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));
仔细阅读 documentation of malloc
. It can fail, and when it does fail, malloc
returns NULL
(and the failure reason is given by errno
which you often display using perror
).
所以你应该针对 malloc
的失败进行测试。典型代码至少为:
u = (double**)malloc(Size*sizeof(double*));
if (u==NULL) { perror ("malloc u"); exit(EXIT_FAILURE); };
同样适用于您的 rho_u
和每个 rho_u[i]
一些操作系统可能提供 memory overcomitment。这是我不喜欢的功能。
考虑完全初始化每个内存区域。在有效内存区域(或有效地址)之外使用内存是 undefined behavior (and your program have one, noticed by
我也推荐使用 valgrind。这是一个非常方便的工具,可以用来寻找与内存相关的错误,并且可以检测到您的错误。
您可能在此处损坏了您的堆:
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));
第二个循环相同。
观察:
- 避免类型转换
malloc()
,阅读 Do I cast the result of malloc? - 检查
malloc()
的 return 值并进行正确的错误处理。 - 将循环条件从
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_u
和 rho
类似。