2016-02-06 64 views
1

我有一個看起來像這樣的結構:malloc的結構與雙指針

typedef struct{ 
    char* name; 
    int count; 
    Node **subnodes; 
}Node; 

我收到的名字和一個爲整個k元樹算過網絡之一,然後我重建樹。我如何malloc這個結構?

Node *n = NULL; 
fun(n, buf); //call function fun 

void fun(Node *n, void *buf){ 
    //successfully extracted name and count from buf 
    // say count is 5, i.e. this node should have 5 subnodes and 
    // name is root 
    n = malloc(sizeof(*n)+strlen(name)); 
    n->name = name; 
    n->count = count; 
    for(int i=0; i<n->count;i++) 
     fun(n->subnodes[i], buf+some_increment); 
} 

只要我第二次給我打電話,這個就崩潰了。我應該如何正確地使用malloc?我應該malloc - 每個子節點?

+0

什麼是' count'?請發佈[最小,完整和可驗證示例]( http://stackoverflow.com/help/mcve)。沒有看到你的其他變數很難說。 –

+0

我明白,但正如我在代碼中所評論的那樣,這是一個從網絡接收到的值,我證實它是一個正確的整數。把所有的代碼放在這個問題上都是不必要的。 – Neo

+0

你'收到姓名並通過網絡計數'令我困惑。 你知道節點指向/應該指向哪個節點嗎?另外,至少在C++中不要使用NULL。 –

回答

3

首先,你意識到這是泄漏? n只是在堆棧上 - 你沒有返回它或「保存」你永久在任何地方給它的值。

然後你實際上沒有爲subnodes分配任何內存,所以通過索引到它你正在讀取未分配的內存。

沒有一個更完整的例子,它是很難進一步,但至少你需要malloc東西subnodes

1

我有一個看起來像這樣的結構:

typdef struct{ 
     char* name; 
     int count; 
     Node **subnodes; 
    }Node; 

不是真的,因爲它是不typedeftypdef

正如John3136所指出的,你的函數在n中分配內存,這是一個局部變量。另外,您正在分配countname,這似乎不會傳遞給fun

它在我看來像功能fun將無限期遞歸。

你叫fun這(最後一行)調用fun因此這再次呼籲fun,依此類推,直到用完棧。


(編輯補充)

試圖猜測是想要的,我有這方面的工作例如去:

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

typedef struct Node { 
    char* name; 
    int count; 
    Node **subnodes; 
}Node; 

void makeNode(Node * &n, const char * name, const int count) 
    { 
    // make the node itself 
    n = (Node *) malloc(sizeof(*n)); 
    // allocate room for the name 
    n->name = (char *) malloc (strlen (name) + 1); 
    // copy in the name 
    strcpy (n->name, name); 
    // save the count of subnodes 
    n->count = count; 
    // allocate memory for subnode pointers (not the subnodes themselves) 
    if (count > 0) 
    n->subnodes = (Node **) malloc (sizeof (Node *) * count); 
    else 
    n->subnodes = NULL; 
} // end of makeNode 

int main() 
    { 
    Node *node = NULL; 
    makeNode(node, "foo", 3); 
    makeNode(node->subnodes [0], "the", 0); 
    makeNode(node->subnodes [1], "slithy", 0); 
    makeNode(node->subnodes [2], "toves", 0); 

    for (int i = 0; i < 3; i++) 
    printf ("Node %i, name = %s\n", i, node->subnodes [i]->name); 
    printf ("Done!\n"); 
    } // end of main 

這運行正常:

Node 0, name = the 
Node 1, name = slithy 
Node 2, name = toves 
Done! 

請注意,我用g ++編譯,而不是gcc。但它應該給你一些想法繼續下去。

(您不必引用在C,所以你真的需要C++這個工作)

+0

就像我在問題中寫的那樣,'buf'給出了名字和數量。 – Neo

+0

'void * buf'給出名字和數量?怎麼樣? –

+0

這是一個網絡數據包。我提取它,我可以向你保證它給出正確的整數和char *名稱。假設你知道伯爵和名字,那麼怎麼做呢? – Neo

3

是的,你將不得不malloc的每個節點。我看到一對夫婦的問題在這裏:

  1. 您在malloc(sizeof(*n)+strlen(name))忽略了爲空終止空間。本聲明應爲malloc(sizeof(*n)+strlen(name)+1)。另外,應在結構名稱指針設置爲結構的末端,然後STRCPY緩衝的名字給它

    n -> name = (char *)(n + 1) strcpy(n -> name, buffered_name)

    我相信緩衝的版本是短暫的。

  2. 您正在爲可變尺寸的子節點數組分配空間。這有許多工作要做作爲一個單獨的malloc或你必須將它嵌入在節點的malloc(我建議你把它放在節點標題和名稱字符串內容之間。

注意,我做了一些什麼代碼有的樣子,因爲這顯然是一個不完整的這段有錯別字寬鬆的假設如子節點< - >子節點

附錄:代碼段(未經測試,從而正常地告誡):

typedef struct 
{ 
    char* name; 
    int count; 
    Node **subnodes; 
} 
    Node; 

Node *fun(void *buf) 
{ 
    ... 
    //successfully extracted name and count from buf 
    // say count is 5, i.e. this node should have 5 subnodes and 
    // name is root 

    // Allocate space for the node and its data. 
    Node *node_ptr = malloc(sizeof(Node) + count * sizeof(Node *) + strlen(name) + 1); 

    // Set the name pointer and copy the name from the I/O buffer. 
    node_ptr -> name = (char *)(node_ptr + 1) + count * sizeof(Node *); // set the name pointer to the right location. 
    strcpy(node_ptr -> name, name); // copy the buffered value to the node value. 

    // Establish the count from the I/O buffer. 
    node_ptr -> count = count; 

    // Set the subnodes address. 
    node_ptr -> subnodes = (char *)(node_ptr + 1); 

    // Get the child nodes. 
    for(int child = 0; child < node_ptr -> count; child++) 
     node_ptr -> subnodes[child] = fun(buf + some_increment); 
} 
+0

謝謝肯。你可以添加一個片段或例子嗎?我需要malloc n個子節點嗎?或者當函數被遞歸調用時,它將通過malloc調用正確完成? – Neo

+0

結構來自庫。我不能修改結構本身。所以我一開始就被冠以名字。 – Neo

+0

那麼'n'是什麼?你的術語很混亂。在你的代碼中'n'是一個Node,現在你問你是否應該分配'n'個子節點?多少個子節點?根據這個事實,「fun」(你不能更好的稱呼?)應該爲它的參數'n'分配一些東西,你至少應該通過引用來傳遞它。 –