繁体   English   中英

如何在另一个 function 中释放我用 malloc 分配的双指针

[英]How to free my double pointer allocated with malloc in another function

我想释放双指针,问题是我收到另一个双指针作为参数,它实际上复制了我想要释放的那个,但这意味着它实际上并没有释放原件,所以我怎样才能释放原件另一个 function。

我试过传递一个双指针作为参数和一个指向这个双指针的指针,但这些都不起作用。

int main(){

    int ** matrix;
    int rows = 5;
    int cols = 6;
    matrix = createMatrix(rows, cols);
    printf("%d\n", matrix[2][3]);
    freeMatrix(matrix, rows);
    printf("%d\n", matrix[2][3]);
}
int** createMatrix(int row, int col){
    int **m = (int **)malloc(row * sizeof(int*));
    for(int x = 0; x < row; x++){
        m[x] = (int *)malloc(col * sizeof(int));
    }
    return m;
}
void freeMatriz(int **m, int row){
    for(int x = 0; x < row; x++){
        free(m[x]);
    }
    free(m);
}

我试图在免费前后打印一个 position,比如说矩阵 [2] [3]; 但是在打印后两次打印数字都不应该,因为 memory 中的空间应该被释放,这显然没有发生。

除了中的错字

void freeMatriz(int **m, int row)
              ^

这正确地释放了 memory。 释放矩阵后的 printf 实际上应该导致访问冲突。 当使用更大的 1024x2048 矩阵进行测试时,会发生这种情况。 我的理论如下...

  1. memory 尚未回收,仍在计划范围内...
  2. 垃圾收集或其他东西的某种延迟..哈哈

我将把它留给那些可能知道为什么第二个 printf 使用如此小的 memory 空间被分配这样做的人.. ;) 很想知道确切的原因..

如果您使用调试器逐步执行此操作,您将看到 memory 确实被正确释放,如果使用调试器逐步执行,第二个 printf 会导致访问冲突...所以它必须与 Z50484C19F1AFDAF3D24 相关

如果您在任务管理器中查看工作集和 Memory 分配,并在 free 之前放置一个 system("pause") 或 getchar() (您想要的任何类型的中断)..您可以分配一个大矩阵,签入在任务管理器中...恢复程序(空闲后再次休息)。 您会看到 memory 正在发布。 :)

您的两个主要问题是:

  1. 您未能验证每个分配的返回,因此malloc可能失败并且您无法知道;
  2. After allocating storage for your integer values, you fail to initialize the memory, leaving the memory holding whatever garbage values happened to be present at that memory location (you can, and in the case of your integer allocations, use calloc to allocate and initialize at同时,或使用memset做同样的事情)

您在free()之前访问matrix[2][3]的尝试只是访问一个未初始化的 4 字节 memory ,其中包含碰巧存在的任何位。 您在free()调用Undefined Behavior之后访问matrix[2][3]的尝试。 free()之后,您将无法再有效访问已释放的 memory。

If you allocate, you must validate... It's not a matter of if malloc can fail returning NULL , it is a matter of when malloc fails returning NULL . 要处理失败情况,您必须始终检查您使用的分配 function 的返回(就像您对每个输入函数所做的那样)。 很简单,如果malloc返回NULL分配失败。 所以只需检查,例如

int **creatematrix (int row, int col)
{
    int **m = malloc (row * sizeof *m);

    if (!m) {                   /* if you allocate -- you must VALIDATE */
        perror ("malloc-m");
        return NULL;
    }

    for (int x = 0; x < row; x++) {
        if (!(m[x] = malloc (col * sizeof *m[x]))) {    /* ditto */
            perror ("malloc-m[x]");
            while (x--)         /* on error free any allocated memory */
                free (m[x]);
            free (m);           /* before returing NULL */
            return NULL;
        }
    }

    return m;
}

( note: before returning NULL you should free() any memory you have allocated up to that point to prevent a memory leak when you return NULL )

在您调用 function (此处为main() )时,您需要验证creatematrix function 的返回以确定分配的成功/失败 -您使用 ZCD69B4957F0190CD8191ZBFD 例如之前

int main (void) {

    int **matrix,
        rows = 5,
        cols = 6;

    if (!(matrix = creatematrix (rows, cols)))  /* VALIDATE allocations */
        exit (EXIT_FAILURE);

    for (int i = 0; i < rows; i++) {        /* loop initializing all values */
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i * cols + j;
            printf (" %3d", matrix[i][j]);  /* output all values */
        }
        putchar ('\n');
    }

    freematrix (matrix, rows);              /* free all allocated memory */
}

现在你可以free()所有 memory (除了你做的正确的'z'而不是'x'的错字)。 总而言之,您可以这样做:

#include <stdio.h>
#include <stdlib.h>

int **creatematrix (int row, int col)
{
    int **m = malloc (row * sizeof *m);

    if (!m) {                   /* if you allocate -- you must VALIDATE */
        perror ("malloc-m");
        return NULL;
    }

    for (int x = 0; x < row; x++) {
        if (!(m[x] = malloc (col * sizeof *m[x]))) {    /* ditto */
            perror ("malloc-m[x]");
            while (x--)         /* on error free any allocated memory */
                free (m[x]);
            free (m);           /* before returing NULL */
            return NULL;
        }
    }

    return m;
}

void freematrix (int **m, int row)
{
    for (int x = 0; x < row; x++)
        free (m[x]);

    free (m);
}

int main (void) {

    int **matrix,
        rows = 5,
        cols = 6;

    if (!(matrix = creatematrix (rows, cols)))  /* VALIDATE allocations */
        exit (EXIT_FAILURE);

    for (int i = 0; i < rows; i++) {        /* loop initializing all values */
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i * cols + j;
            printf (" %3d", matrix[i][j]);  /* output all values */
        }
        putchar ('\n');
    }

    freematrix (matrix, rows);              /* free all allocated memory */
}

示例使用/输出

$ ./bin/freematrix
   0   1   2   3   4   5
   6   7   8   9  10  11
  12  13  14  15  16  17
  18  19  20  21  22  23
  24  25  26  27  28  29

Memory 使用/错误检查

在您编写的任何动态分配 memory 的代码中,对于分配的 memory 的任何块,您有两个责任:(1)始终保留指向 ZCD69B4957F06CD818D7BF3D21980 块的起始地址的指针,所以它可以被释放,更需要。

您必须使用 memory 错误检查程序,以确保您不会尝试访问 memory 或写入超出/超出分配块的范围,尝试读取或基于未初始化值的条件跳转,最后确认释放所有已分配的 memory。

对于 Linux valgrind是正常的选择。 每个平台都有类似的 memory 检查器。 它们都易于使用,只需通过它运行您的程序即可。

$ valgrind ./bin/freematrix
==17080== Memcheck, a memory error detector
==17080== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17080== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==17080== Command: ./bin/freematrix
==17080==
   0   1   2   3   4   5
   6   7   8   9  10  11
  12  13  14  15  16  17
  18  19  20  21  22  23
  24  25  26  27  28  29
==17080==
==17080== HEAP SUMMARY:
==17080==     in use at exit: 0 bytes in 0 blocks
==17080==   total heap usage: 6 allocs, 6 frees, 160 bytes allocated
==17080==
==17080== All heap blocks were freed -- no leaks are possible
==17080==
==17080== For counts of detected and suppressed errors, rerun with: -v
==17080== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认您已释放所有已分配的 memory 并且没有 memory 错误。

如果您还有其他问题,请仔细查看并告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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