簡體   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