我正在编写一个数值程序来近似求解一个双曲型方程。
在for循环的每次迭代中,我必须为两个一维数组和两个二维数组分配内存。所以我在每次迭代中都会分配内存和free内存。
代码是
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);
}free语句不起作用。如果我尝试只对1D数组t和x进行free,那么在第二次迭代之后,我会得到一个segmentation fault错误。
如果尝试仅对2d阵列u和u_exact执行free操作,则会出现错误
*** glibc detected *** ./a.out: double free or corruption (!prev): 0x0900a968 ***发布于 2014-09-29 02:11:46
我怀疑你的内存快用完了。在循环中,内存分配似乎呈指数级增长。
对于MAX_MESH为8,如果我们选择最后一个迭代,这将是最坏的情况:
我假设双倍大小是8字节。
m_max = 2^12
n_max = 2^16
所需内存(字节):
T= (2^16 + 1) * ( 2^3 ) = 2^19 +2^3
X= (2^12 + 1) * ( 2^3 ) = 2^15 +2^3
U= (2^12 + 2) * (2^16) * (2^3) = 2^31 + 2^20 (近似)
u_exact = 2^31 + 2^20 (约)
为简洁起见,我省略了在u和u_exact计算中存储每个行指针所需的内存。
看看u和u_exact所需的巨大内存吧!
现在,如果您在32位系统中运行,那么您的进程肯定没有足够的虚拟内存可供使用。我期望在矩阵分配函数中由malloc返回一个"NULL“指针。您是否正在检查返回值并打印类似于您在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;
}如果请求的分配量很大(缺省值为128KB),则malloc调用mmap,Refer http://man7.org/linux/man-pages/man3/malloc.3.html。mmap受到RLIMIT_DATA资源限制的限制。您可以通过运行命令"ulimit -v“检查系统中某个进程的虚拟内存限制。如果它返回"unlimited“,那么就没有限制。
我们可以通过将MAX_MESH值减少到4来确认内存是否有问题(如果您想要在32位机器中签入)。如果您在64位机器上运行相同的程序,我希望它能够正常运行,因为可用的虚拟内存必须足以满足MAX_MESH值8的要求。
发布于 2014-09-29 03:56:54
代码耗尽内存,并打印一个错误,但仍然继续执行,就好像分配工作一样!
代码需要更改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]);以下代码会在失败时泄漏内存,因为分配的矩阵指针和分配的部分列都会丢失。可以释放已分配的部件或错误,如下所示。其他方法也存在。
/* 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);
}
}使用size_t而不是int作为数组大小是C方法,因为在调整内存大小时,int的大小不是确定的类型。注意,size_t是未签名的。
一次分配所有内存是另一种方法。这可能会有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;
}https://stackoverflow.com/questions/26085550
复制相似问题