[英]Free Memory of 2d Array in struct
我正在 C 寫一個小游戲,我想用 Valgrind 測試它。 這是一個小代碼示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct Game {
int** field;
} Game;
void buildfield(Game* game, int length);
void printfield(Game* game, int length);
void freefield(Game* game, int length);
int main()
{
struct Game* game = NULL;
game = malloc(sizeof (struct Game));
buildfield(game, 10);
printfield(game, 10);
freefield(game, 10);
free(game);
return 0;
}
void buildfield(Game* game, int length)
{
game->field = (int**)malloc((sizeof (int*)) * 20);
int i;
for (i = 0; i < 20; i++) {
game->field[i] = (int*) malloc((sizeof (int)) * length);
}
for (int line = 0; line < length; line++) {
for (int col = 0; col < 81; col++) {
game->field[col][line] = 0;
}
}
}
void printfield(Game* game, int length)
{
for (int i = 0; i < length; i++) {
printf("\n");
for (int j = 0; j < 20; j++) {
printf("%d",game->field[i][j]);
}
}
}
void freefield(Game* game, int length)
{
for (int i = 0; i < length; ++i) {
free(game->field[i]);
}
free(game->field);
}
Valgrind 說:
HEAP SUMMARY:
==6239== in use at exit: 968 bytes in 22 blocks
==6239== total heap usage: 22 allocs, 0 frees, 968 bytes allocated
為什么我不釋放分配?
那么在 function buildfield() 你已經分配了 20 個塊 memory
game->field = (int **) malloc(sizeof(int *) * 20);
因此,您最多可以通過 [] 運算符訪問 game->field[19] 但是在循環中,程序會嘗試在 game->field[19] 之前訪問更多塊,從而導致分段錯誤並且程序會在那里崩潰。 無需返回 main(),更不用說到達 free() 語句了。 所以這意味着你的程序一開始就沒有完成並且中途崩潰了。
for (int line = 0; line < length; line++)
{
for (int col = 0; col < 81; col++) //when col becomes 20
{
game->field[col][line] = 0; //this statement will try to access the non-alloted memory block when col is 20
}
}
要檢查您的程序是否中途崩潰,請在與訪問 memory 相關的語句末尾添加一些打印語句或使用調試器。 因為這是最常見的運行時錯誤來源。
同樣對於此代碼,請記住最大編號。 分配的 memory 個塊中,可以由特定指針訪問,並更改標記的 for 循環的條件,以便它將在分配限制內訪問 memory,即第 2 個。 您使用 malloc function 分配的塊數。
這里的問題不是 free() 不工作。 但是分段錯誤。 假設您提供的代碼是您的代碼的精確副本
“為什么我不釋放分配?”
如評論中所述,由於使用無法解釋的值( 幻數)創建和釋放 memory,導致代碼更加復雜。由於鏈接中解釋的原因,除其他問題外,這可以使匹配的釋放計數與計數分配困難。 由於 Valgrind 指示在執行結束時剩余的 memory 塊,因此調用這些中的每一個的時間不匹配。
以下是您的代碼和建議,包括那些明確應用與[m][c]alloc()
相同數量的調用free()
的代碼(我選擇在此處使用calloc()
以避免另一個循環(或memset()
) 來初始化 memory。)
另請注意,您可能需要更改此示例用於 #defines 的值以滿足您的需要,但您只需在一個地方(在文件頂部)更改它們。
typedef struct Game {
int** field;
} Game;
void buildfield(Game *game, int length);
void printfield(Game *game, int length);
void freefield(Game *game, int length);
#define COUNT 20//replace all magic numbers
#define LENGTH 10//(change values of #defines to change shape and size of memory)
int main(void)//use a complete prototype for main
{
struct Game* game = NULL;//pointer needs memory
game = malloc(sizeof (struct Game));
buildfield(game, LENGTH);
printfield(game, LENGTH);
freefield(game, LENGTH);
free(game);
return 0;
}
void buildfield(Game *game, int length)
{ //Note - not optimal to cast return of [c][m]alloc in C (only in C++)
game->field = calloc(COUNT, sizeof(game->field));
int i;
for (i = 0; i < COUNT; i++) {
game->field[i] = calloc(LENGTH, (sizeof (game->field[i])) );
}
}
void printfield(Game *game,int length)
{
for (int i = 0; i < COUNT; i++) {
printf("\n");
for (int j = 0; j < LENGTH; j++) {
printf("%d",game->field[i][j]);
}
}
}
void freefield(Game *game,int length)
{
for (int i = 0; i < COUNT; ++i) {
free(game->field[i]);
}
free(game->field);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.