C 这个静态分配的结构数据如何在函数外部可用?

C 这个静态分配的结构数据如何在函数外部可用?,c,memory-management,struct,C,Memory Management,Struct,下面是一个快速测试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<

下面是一个快速测试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;
}
#包括
#包括
类型定义结构节点{
int kk;
int zz;
}节点;
节点**创建节点(){
节点**res=(节点**)malloc(节点*)的大小*10;
int i,j;
对于(i=0;ikk);

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

就第一个静态分配(我想)和第二个动态分配而言,这两者之间有什么区别?我在createNode()函数中创建的节点值不应该在超出该函数的范围后被销毁吗


只是有点困惑:我需要有人帮我澄清一下,
节点**
节点***

之间的区别是什么让我们使用一个更简单的函数来制作示例。例如,我们想要创建一个函数,该函数将为整数分配内存并分配一些值。该函数与一个

int* createInt() {
    int *res = malloc(sizeof(int));
    *res = 5;
    return res;
}
此函数创建一个指针并为int分配动态内存。在此之后,该函数返回内存地址,其中int为,但
res
指针不存在。顺便看看类似的问题,值得一读

正如您在所使用的
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
:>


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

让我们使用一个更简单的函数来制作示例。例如,我们希望创建一个函数,该函数将为整数分配内存并赋值。该函数的作用与您的函数相同

int* createInt() {
    int *res = malloc(sizeof(int));
    *res = 5;
    return res;
}
此函数创建一个指针并为int分配动态内存。在此之后,该函数返回内存地址,其中int为,但
res
指针不存在。顺便看看类似的问题,值得一读

正如您在所使用的
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
:>


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

小心!第二个
createInt
示例不起作用。您返回的是一个自动变量的地址;返回的指针是不确定的,您尝试对其执行的几乎任何操作都是未定义的行为。如果调用另一个函数,存储可能会被覆盖十、我返回静态变量的地址,行为是被定义的。例如问题。但是如果我们调用我的函数两次,会导致内存泄漏。哦,它是静态的。这是定义的,虽然不是特别有用。注意!第二个
createInt
示例不起作用。你返回的是自动变量的地址;returned指针是不确定的,几乎任何您试图使用它的操作都是未定义的行为。如果您调用另一个函数,存储可能会被覆盖。我返回静态变量的地址,该行为已定义。例如,问题。但如果我们调用我的函数两次,则会导致内存泄漏。哦,它是静态的。这已定义,th虽然不是特别有用。如果你曾经在一行中键入三星,你应该后退一步,考虑重新设计代码或放入另一个抽象。如果你曾经在一行中键入三星,你应该后退一步,考虑重新设计代码或放入另一个抽象。