2013-11-23 37 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