2013-11-23 67 views
1

這裏是我編寫怎麼看結構的內存分配工作的快速測試C程序...這個靜態分配的結構數據如何在函數外部使用?

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

typedef struct _node { 
    int kk; 
    int zz; 
} node; 

node ** createNode(){ 
    node** res = (node**) malloc(sizeof(node*)*10); 
    int i,j; 
    for(i= 0;i<10;i++){ 
      res[i] = (node*) malloc(sizeof(node)*10); 
      for(j=0;j<10;j++){ 
        res[i][j].kk=33; 
      } 
    } 
    return res; 
} 

int main(void) { 
    node ** g = createNode(); 
    printf("%d",g[0][0].kk); 



    return 0; 
} 

該程序將打印值「33」。現在這已經變得很明顯,但反映在它上面,我不明白爲什麼......

現在我想起來了,應該不是變量gnode ***

而打印語句看起來像printf("%d",g[0][0]->kk);

在第二個版本中,我基本上做了和原始代碼一樣的事情,但我有一個指向節點的指針,而不是實際的節點。

這兩者之間的區別是第一個靜態分配(我認爲)和第二個是動態分配的......並且不應該在我的createNode()函數中創建的節點值被銷燬一次那個函數的範圍之外?

只是有點困惑都是:■我需要有人來澄清這對我來說,是什麼node**node***

+1

如果您連續輸入3顆星,您應該退一步考慮重新設計您的代碼或放入另一個抽象。 – user2357112

回答

1

之間的差異讓我們用一個簡單的功能,使樣品。例如,我們想創建一個函數,它將爲整數分配內存並分配一些值。該功能與您的功能完全相同。

int* createInt() { 
    int *res = malloc(sizeof(int)); 
    *res = 5; 
    return res; 
} 

此函數爲int創建一個指針並分配動態內存。在此之後,該函數返回內存地址,其中int爲,但res指針不存在。順便看看this answer類似的問題,值得一讀。

正如你在main功能瞭解您使用

int *myInt = createInt();

因爲你要分配分配的內存指針的地址來處理這個和自由畢竟。

但你可以做到這一點

int** createInt() { 
    static int *res; 
    res = malloc(sizeof(int)); 
    *res = 5; 
    return &res; 
} 

而且在main

int **myInt = createInt();

在這裏,你做同樣的事情上面一樣,但創建靜態指針,它從功能的一個呼叫保留到另一個。所以你可以返回這個指針的地址。它將指向功能結束後的實際數據。

正如在評論中提到的,我的代碼是不安全的,因爲如果你兩次調用這個函數會導致內存泄漏。你可以這樣做

int* createSingletonInt() { 
    static int *res; 
    if (res != NULL) { 
     return res; 
    } 
    res = malloc(sizeof(int)); 
    *res = 5; 
    return res; 
} 

如果你想要處理相同的int,這會很有用。更有用的,如果你處理的東西,但不是int:>

我認爲它可以應用到你的例子。

+0

小心!第二個'createInt'示例**不起作用**。你正在返回一個自動變量的地址;返回的指針是不確定的,幾乎任何你試圖用它做的事都是未定義的行爲。如果您調用另一個功能,存儲可能會被覆蓋。 – user2357112

+0

我返回靜態變量的地址,行爲被定義。例如[this](http://stackoverflow.com/questions/453696/is-returning-a-pointer-to-a-static-local-variable-safe)的問題。但是,如果我們兩次調用函數,會導致內存泄漏。 – Deck

+0

哦,它是靜態的。這是定義的,雖然不是特別有用。 – user2357112