[英]Dynamic memory allocation repetition in C
我對C編程有些新意。 我對動態內存分配有疑問。 以下是主程序中用於內存分配的代碼。
double **mat=(double**)malloc(sizeof(double*)*n);
mat[0]=(double*)calloc(sizeof(double),n*n);
for(i=1; i<n; i++)
mat[i] = mat[i-1] + n;
mat = create_square_matrix(n);
我想調用函數並在函數內的矩陣中創建元素。 我是否再次在函數內部分配內存,如下所示,還是有任何其他方法可以避免這種繁瑣的內存分配重復。 以下是該功能。
`double** create_square_matrix(int n)
{
int i,j,sum=0;
double **array2=(double**)malloc(sizeof(double*)*n);
array2[0]=(double*)calloc(sizeof(double),n*n);
for(i=1; i<n; i++)
array2[i] = array2[i-1] + n;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
sum=sum+j;
array2[i][j]=sum;
}
}
return array2;
}
`上面的函數返回存儲在'mat'變量中的數組。 另一個問題是如何在使用return方法后釋放函數內部變量'array2'的內存。 在返回數組之前,我無法釋放內存。 有沒有一種方法可以釋放上述功能中的內存。
您的函數create_square_matrix分配內存,然后通過某些值填充它。
您的最上面的代碼分配內存,然后調用create_square_matrix再次分配內存。 在打電話給那個也拖地板的看門人之前,就像拖地板一樣。 您不需要兩次分配內存。 不僅是不必要的,事實上它是不好的。 由於您執行了兩次分配,因此第一次的內存將丟失,並且無法釋放它。 這稱為內存泄漏。 代替
double **mat=(double**)malloc(sizeof(double*)*n);
mat[0]=(double*)calloc(sizeof(double),n*n);
for(i=1; i<n; i++)
mat[i] = mat[i-1] + n;
mat = create_square_matrix(n);
你應該寫
double **mat = create_square_matrix(n);
如上所述,在C中沒有必要強制轉換為void * 。 此外,您的calloc
是向后的:第一個參數使用N個元素,第二個參數使用sizeof(元素) 。
我會回答你的問題,然后提出一個更好的方法。
您正在為矩陣選擇double **
。 即使它不是正方形,你也確切知道你需要多少指針和多少雙打,當然每種類型有多大。 所以,
double **M = malloc( n * sizeof(double*) + n * m * sizeof(double) );
訣竅,不是嗎? 如果你的機器的sizeof(double*) == sizeof(double)
(可能是真的),那么
double **M = calloc( (1+n) * m, sizeof(double) );
也有效,但不太方便。 你也可以免費得到零; 你很難找到一台機器,因為double f=0
產生一個所有位都為零的值。
但為什么要將矩陣定義為指針數組? 為什么不把它定義為雙打數組呢?
double *M = calloc( n * m, sizeof(double) );
更好的是,在過去15年左右的時間里,C支持可變長度數組,這意味着您可以定義大小在運行時確定的數組。 回到K&R天,您可以定義一個數組M[n]
除非n是靜態常量或枚舉。 如果你的數組不是巨大的 - 這意味着對於有問題的機器它們可以很好地適應堆棧 - 你可以跳過malloc
並簡單地通過在運行時確定的大小來定義矩陣。
即使你不能這樣做,也可以動態地輸入一個維度,
typedef double (x_axis_t)[m];
double x_axis_t *M = calloc( n * sizeof(x_axis_t), sizeof(double) );
這很好,因為那時你可以訪問你的數組
M[x][y];
只是不要嘗試使用M[x,y]
,因為這完全不同於其他東西。
順便說一句,既然你是游戲新手,使用c99編譯器,標准命令是c99 ,而不是cc 。 有關詳細信息,請參閱友好手冊 :-)
使用一個很好的函數宏進行內存分配總是一個好主意。 除非你必須手動釋放內存,否則我會將它留給垃圾收集器,例如libgc。 以下是一個例子。 如果您不想使用垃圾收集器,則可以使用malloc替換GC_MALLOC 。 釋放陣列(手動)時,必須先釋放各行。
#include <gc/gc.h>
#include <stdio.h>
#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = GC_MALLOC((n) * sizeof (ptr)[0])
double **SquareMatrix(int n)
{
double **A;
int i, j;
NEW_ARRAY(A, n);
for (i = 0; i < n; i++) {
NEW_ARRAY(A[i], n);
for (j = 0; j < n; j++) {
A[i][j] = 0.0;
}
}
return A;
}
int main(void)
{
const int n = 5;
double **A;
int i, j;
A = SquareMatrix(n);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%5.2f ", A[i][j]);
}
putchar('\n');
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.