簡體   English   中英

C中的動態內存分配重復

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM