【问题标题】:How is this statically allocated struct data available outside the function?这个静态分配的结构数据如何在函数外部可用?
【发布时间】:2013-11-23 04:07:15
【问题描述】:

这是我编写的一个快速测试 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”。现在这对我来说已经很明显了,但仔细想想,我不明白为什么......

现在想想,变量g不应该是node ***类型吗?

打印语句看起来像printf("%d",g[0][0]-&gt;kk);

在第二个版本中,我基本上做了与原始代码相同的事情,但我有一个指向节点而不是实际节点的指针。

就第一个是静态分配的(我认为)和第二个是动态分配的而言,两者之间有什么区别......我在 createNode() 函数中创建的节点值不应该在外部被销毁该功能的范围?

只是有点困惑:S 我需要有人为我澄清一下,node**node*** 之间有什么区别

【问题讨论】:

  • 如果您曾经连续输入 3 颗星,您应该退后一步,考虑重新设计您的代码或放入另一个抽象。

标签: c memory-management struct


【解决方案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();

在这里,您执行与上述相同的操作,但创建静态指针,以便从函数的一次调用到另一次调用时保留它。所以你可以返回这个指针的地址。函数结束后会指向实际数据。

如 cmets 中所述,我的代码不安全,因为如果您两次调用此函数会导致内存泄漏。你可以这样做

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

如果您想处理相同的 int,这会很有用。如果您处理某些事情而不是int,则更有用:>

我认为它可以应用于您的示例。

【讨论】:

  • 小心!第二个createInt 示例不起作用。您正在返回自动变量的地址;返回的指针是不确定的,几乎你试图用它做的任何事情都是未定义的行为。如果你调用另一个函数,存储可能会被覆盖。
  • 我返回静态变量的地址,行为已定义。例如this 问题。但是是的,如果我们两次调用我的函数会导致内存泄漏。
  • 哦,它是静态的。这是已定义的,虽然不是特别有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多