简体   繁体   English

无法释放分配给一维和二维数组的内存

[英]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数组tx ,则在第二次迭代后会出现segmentation fault错误。

If try to only free the 2d-arrays u and u_exact I get the error 如果尝试仅free 2d数组uu_exactu_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM