[英]Can't free memory allocated one and two dimension arrays
I'm working on a numeric program to approximate solutions of an hyperbolic equation. 我正在研究一个数值程序来近似双曲方程的解。
I have to allocate memory for two 1d-arrays and two 2d-arrays every iteration of a for loop. 我必须为for循环的每次迭代为两个1d数组和两个2d数组分配内存。 So I allocate memory and
free
memory in every iteration. 所以我在每次迭代中分配内存和
free
内存。
The code is 该代码是
int main()
{
int mesh, n_max, m_max;
int i;
double v, delta_t, delta_x, lambda;
double *t, *x, **u, **u_exact, error[MAX_MESH];
for (mesh = 0; mesh < MAX_MESH; mesh++) {
m_max = pow(2, 5) * pow(2, mesh);
n_max = 16 * m_max;
t = vector_alloc((n_max + 1) * sizeof(double));
x = vector_alloc((m_max + 2) * sizeof(double));
u = matrix_alloc(m_max + 2, n_max);
u_exact = matrix_alloc(m_max + 2, n_max);
//functions manipulating t, x, u, u_exact
free(t);
free(x);
for (i = 0; i < m_max + 2; i++) free(u[i]);
free(u);
for (i = 0; i < m_max + 2; i++) free(u_exact[i]);
free(u_exact);
}
return (0);
}
double *vector_alloc(int n)
{
double *result; /* ponteiro para o vetor */
result = malloc(n * sizeof(double));
if (result == NULL) printf("Error: no memmory available");
return(result);
}
double **matrix_alloc(int m, int n)
{
int i;
double **result;
/* Allocates matrix raws */
result = malloc(m * sizeof(double *));
if (result == NULL) {
printf ("Error: no memmory available");
return (NULL);
}
/* Allocates matrix columns */
for (i = 0; i < m; i++) {
result[i] = malloc(n * sizeof(double));
if (result[i] == NULL) {
printf ("Error: no memmory available");
return (NULL);
}
}
return (result);
}
The free
statements are not working. free
声明不起作用。 If I try to only free
the 1d-arrays t
and x
, after the second iteration I get a segmentation fault
error. 如果我尝试仅
free
1d数组t
和x
,则在第二次迭代后会出现segmentation fault
错误。
If try to only free
the 2d-arrays u
and u_exact
I get the error 如果尝试仅
free
2d数组u
和u_exact
, u_exact
收到错误消息
*** glibc detected *** ./a.out: double free or corruption (!prev): 0x0900a968 ***
I suspect that you are running out of memory. 我怀疑您的内存不足。 The memory allocation seems to be growing exponentially in the loop.
内存分配似乎在循环中呈指数增长。
For MAX_MESH as 8, if we take the last iteration which will be the worst case : 对于MAX_MESH为8,如果我们进行最后一次迭代,那将是最坏的情况:
I assume double size is 8 bytes. 我假设双倍大小是8个字节。
m_max = 2^12 m_max = 2 ^ 12
n_max = 2^16 n_max = 2 ^ 16
Memory required in bytes by : 所需的内存字节数:
t = (2^16 + 1) * (2^3) = 2^19 + 2^3 t =(2 ^ 16 +1)*(2 ^ 3)= 2 ^ 19 + 2 ^ 3
x = (2^12 + 1) * (2^3) = 2^15 + 2^3 x =(2 ^ 12 +1)*(2 ^ 3)= 2 ^ 15 + 2 ^ 3
u = (2^12 + 2) * (2^16) * (2^3) = 2^31 + 2^20 (approx) u =(2 ^ 12 + 2)*(2 ^ 16)*(2 ^ 3)= 2 ^ 31 + 2 ^ 20(大约)
u_exact = 2^31 + 2^20 (approx) u_exact = 2 ^ 31 + 2 ^ 20(大约)
For brevity, I left out the memory required to store each row pointer in u and u_exact calculation. 为简便起见,我省略了在u和u_exact计算中存储每个行指针所需的内存。
See the enormous memory required for u and u_exact! 看到u和u_exact所需的巨大内存!
Now, if you are running in a 32 bit system, then definitely your process will not have sufficient virtual memory to use. 现在,如果您在32位系统上运行,那么肯定您的进程将没有足够的虚拟内存供使用。 I would expect a "NULL" pointer returned by malloc in the matrix allocation function.
我希望矩阵分配函数中的malloc返回一个“ NULL”指针。 Are you checking the return value and printing an error message similar to what you are doing in vector_alloc (like below)?
您是否正在检查返回值并打印类似于在vector_alloc中所做的错误消息(如下所示)?
double **matrix_alloc(int m, int n)
{
int i;
double **p = malloc(sizeof(double **) * m);
if(!p) {printf("matrix_alloc:: Unable to allocate memory!!! \n");}
for (i = 0; i < m; i++)
{
p[i] = malloc(sizeof(double) * n);
if(!p[i]) {printf("matrix_alloc:: Unable to allocate memory!!! \n");}
}
return p;
}
malloc calls mmap if the allocation requested is large (the default is 128 KB) Refer http://man7.org/linux/man-pages/man3/malloc.3.html . 如果请求的分配很大(缺省值为128 KB),则malloc调用mmap。请参阅http://man7.org/linux/man-pages/man3/malloc.3.html 。 mmap is restricted by RLIMIT_DATA resource limit.
mmap受RLIMIT_DATA资源限制的限制。 You can check the virtual memory limit for a process in your system by running the command "ulimit -v".
您可以通过运行命令“ ulimit -v”来检查系统中进程的虚拟内存限制。 If it returns "unlimited" then there is no restriction.
如果返回“ unlimited”,则没有限制。
We can confirm whether memory is a problem by reducing the MAX_MESH value to 4 (if you want to check in a 32 bit machine). 我们可以通过将MAX_MESH值减小为4来确认内存是否有问题(如果您要检入32位计算机)。 If you run the same program in a 64 bit machine, I would expect it to go through fine as the virtual memory available must be sufficient for your MAX_MESH value of 8.
如果您在64位计算机上运行相同的程序,我希望它可以正常运行,因为可用的虚拟内存必须足以满足您的MAX_MESH值8。
Code runs out of memory, and prints an error, yet still continues on as if the allocation worked! 代码用完了内存,并显示错误,但仍然继续工作,好像分配正常!
Code needs to change freeing of u
an u_exact
. 代码需要更改
u
u_exact
释放。
// for (i = 0; i < m_max + 2; i++) free(u[i]);
if (u != NULL) for (i = 0; i < m_max + 2; i++) free(u[i]);
The following leaks memory on failure as both the allocated matrix pointer and the partial columns allocated are lost. 由于分配的矩阵指针和分配的部分列都丢失,因此以下操作会在失败时泄漏内存。 Could free allocated parts or error as below.
可以释放分配的零件或出现以下错误。 Other approaches exist.
存在其他方法。
/* Allocates matrix columns */
for (i = 0; i < m; i++) {
result[i] = malloc(n * sizeof(double));
if (result[i] == NULL) {
// add 2 lines
do { free(result[i]); } while (i-- > 0);
free(result);
printf ("Error: no memmory available");
return (NULL);
}
}
Using size_t
rather than int
for array size is the C way as the size of int
is not the definite type to use when sizing memory. C方式是使用
size_t
而不是int
作为数组大小,因为int
的大小不是确定内存大小时要使用的确定类型。 Note that size_t
is unsigned. 请注意,
size_t
是无符号的。
Allocating the memory all at once is a another approach. 一次分配所有内存是另一种方法。 That may have alligmnet issues though, so follows is a 2 allocation approach.
但是,这可能会出现alligmnet问题,因此下面是2分配方法。
void matrix_free(double **ptr) {
if (ptr) {
free(*ptr);
free (ptr);
}
}
double **matrix_alloc(size_t m, size_t n) {
double **result = malloc(m * sizeof *result);
double *data = malloc(m * n * sizeof *data);
if (result == NULL || data == NULL) {
free(result);
free(data);
printf ("Error: no memmory available");
return (NULL);
}
for (size_t i=0; i<m; i++) {
result[i] = &data[i*n];
}
return result;
}
void foo(void) {
double **mat = matrix_alloc(3,4);
...
matrix_free(mat);
mat = NULL;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.