2014-07-24 49 views
0

我正在學習如何編寫C函數來接受一個數組並返回一個修改後的數組。如果你不在一個函數中釋放動態分配的內存會發生什麼?

在功能testfunc(這是應該簡單地添加到10輸入數組b的每個元素)我使用mallocnpts數目的整數的分配存儲器。但是因爲我想使用指針返回這個數組,所以我並沒有在函數結尾釋放這個內存。假設我調用這個函數100次,就像我在代碼中做的那樣,所以在代碼中分配的所有內存會發生什麼?代碼100*10*4字節使用的內存量是多少?對於不適用於動態內存分配的函數,我認爲當函數返回最終值並且再次調用它時,分配給變量的內存會消失,然後再次分配內存等等。但我對這種情況會發生什麼感到困惑。

我不能釋放函數內分配的內存,因爲我需要它將數組返回到主函數,但我也需要爲不同的數組調用此函數超過100次,所以如果它繼續分配和再次,它會用完內存

有沒有辦法來檢查代碼使用多少內存? (除了在Mac-OSX上查看Activity Monitor)。

謝謝!

/* code to test returning array from functions */ 

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

int* testfunc(int *a,int npts); 

int main(int argc, char* argv[]) 
{ 
    int *b; 
    int a[10],i,j,npts=10; 

    b=(int *) malloc(sizeof(int)*npts); 

    for (j=0; j <100; j++) 
    { 
     printf("iteration number %d \n",j); 
     for (i=0; i<npts; i++) 
     { 
      a[i]=i; 
      printf("%d \n",a[i]); 
     } 

     b=testfunc(a,npts); 

     printf("returned array \n"); 
     for (i=0; i<npts; i++) 
     { 
      printf("%d \n",b[i]); 
     } 
    } 
    printf("the size of one integer is %d \n",sizeof(int)); 

    return 0; 
} 
int* testfunc(int *b,int npts) 
{ 
    int *c; 
    int i=0; 

    c=(int *) malloc(sizeof(int)*npts); 

    for (i=0; i<npts; i++) 
    { 
     c[i]=b[i]+10; 
    } 

    return c; 
} 

這是可能的解決方案,以避免在函數內部分配存儲器和能夠調用函數多次

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

void testfunc(int *c,int *d,int npts); 

int main(int argc, char* argv[]) 
{ 
    int *a,*b; 
    int i,j,npts=10; 

    a=malloc(sizeof(int)*npts); 
    b=malloc(sizeof(int)*npts); 

    for (j=0; j <100; j++) 
    { 
     printf("iteration number %d \n",j); 
     for (i=0; i<npts; i++) 
     { 
      a[i]=i; 
      printf("%d \n",a[i]); 
     } 

     testfunc(a,b,npts); 

     printf("returned array \n"); 
     for (i=0; i<npts; i++) 
     { 
      printf("%d \n",b[i]); 
     } 
    } 
    printf("the size of one integer is %d \n",sizeof(int)); 

    free(a); 
    free(b); 

    return 0; 
} 
void testfunc(int *c,int *d,int npts) 
{ 
    int i=0; 

    for (i=0; i<npts; i++) 
    { 
     d[i]=c[i]+10; 
    } 
} 

回答

3
c=(int *) malloc(sizeof(int)*npts); 
: 
return c; 

此傳回這兩個存儲器管理它的責任。

完成後它已經成爲來電者的責任(main在此cae)釋放它。

當你真正的問題所在是在這裏main

b=(int *) malloc(sizeof(int)*npts); 
: 
for (some number of iterations) 
    b=testfunc(a,npts); // overwrites b 

在那個「重寫」行,你實際上有內存泄漏,因爲你無法訪問當前分配爲b(包括原本和內存循環的先前迭代)。


而且,順便說一句,請不要投malloc的返回值C.這是沒有必要的,並且可以隱藏某些細微的錯誤,你真的希望有調試: - )

+0

所以在該代碼中,有100內存泄漏和所有內存分配,但我無法訪問它,因此它被浪費? – Guddu

+0

@Guddu:是的,儘管當進程退出時它會自動放開。這實際上並沒有保證這個標準,但是我從來沒有見過一個讓程序退出後馬特內存掛起的實現。 – paxdiablo

+0

也關於你的回答'這回傳了內存和管理它的責任',所以如果我在主函數中釋放'b',它會自動釋放'c'嗎? – Guddu

2

由於正在使用的malloc ,這意味着要從堆棧分配存儲器。
你應該首先弄清楚堆和堆棧的機制。在C中,malloc將幫助程序員從堆中分配內存,與在C++中使用新的一樣。
因此,即使函數返回最終值,分配的內存也不會被釋放。如果您調用函數100次,它將爲您分配100次內存。
至於工具,你可以參考Valgrind,這是一個強大的工具來檢查是否存在內存錯誤。

0

如果動態分配的內存未被釋放,則會導致內存泄漏並導致系統內存不足。這可能導致程序崩潰。

-1

嘿調用引用的目標是修改輸入指針並返回給調用者。 表示修改後的值,即仍與調用者的地址。

可以簡單地做修改,而不分配內存在函數

只需校正在第二種方法

空隙testfunc(INT * C中,int NPTS) { INT I = 0;

for (i=0; i<npts; i++) 
{ 
    c[i] += 10; //YOU JUST INCREMENT VALUE by 10 
} 

}

我的方法寫功能:

  1. 沒有內存分配
  2. 沒有多個參數
  3. 保持必要的輸入,輸出參數,返回值
  4. 這裏INT * c,npts - 輸入參數,輸出[在int * c位置修改您的值]
0

這是主要必須釋放()分配的空間,但你必須確保你不修改函數期間的空間值。

相關問題