静态vs.Malloc

静态vs.Malloc,c,memory-management,malloc,C,Memory Management,Malloc,与使用malloc相比,块范围中的static关键字有什么优势 例如: 职能A: f() { static int x = 7; } 职能B: f() { int *x = malloc(sizeof(int)); if (x != NULL) *x = 7; } 如果我理解正确,两个程序都会创建一个存储在堆上的整数7。在一个实例中,在主方法执行之前,在某个永久存储器的最开始处创建变量。在B中,一旦调用函数,您就在现场分配内存,然后在指针指向的位置存储

与使用malloc相比,块范围中的static关键字有什么优势

例如:

职能A:

f() {
    static int x = 7;
}
职能B:

f() {
    int *x = malloc(sizeof(int));
    if (x != NULL)
        *x = 7;
}
如果我理解正确,两个程序都会创建一个存储在堆上的整数7。在一个实例中,在主方法执行之前,在某个永久存储器的最开始处创建变量。在B中,一旦调用函数,您就在现场分配内存,然后在指针指向的位置存储一个7。在何种情况下,您可以使用一种方法而不是另一种方法?我知道你不能在函数A中释放x,所以B不是更可取吗

两个程序都创建一个存储在堆上的
整数7

不,他们没有。
static
创建具有静态存储持续时间的对象,该对象在程序的整个生命周期内保持活动状态。而动态分配的对象(由
malloc
创建)保留在内存中,直到被
free
明确删除。两者都提供不同的功能<代码>静态在函数调用中保持对象的状态,而动态分配的对象不保持状态

在何种情况下,您可以使用一种方法而不是另一种方法?

当您希望对象在程序的整个生命周期内处于活动状态并在函数调用中保持其状态时,可以使用
static
。如果您在多线程环境中工作,那么所有线程都将共享相同的
静态
对象,因此需要同步


当您明确希望控制对象的生存期时,可以使用
malloc
。例如:确保对象的生存期足够长,直到函数调用后调用方访问它为止。(一旦函数的作用域
{}
结束,自动/本地对象将被解除分配)。除非调用方显式调用
free
,否则分配的内存将泄漏,直到操作系统在程序退出时回收。

在函数A中,您使用静态存储持续时间分配
x
,这通常意味着它不在堆上(大多数人认为是堆上的)。相反,它只是保证在程序运行的整个过程中都存在的内存

在函数B中,您每次进入函数时都会分配存储空间,然后(除非有
空闲的
您没有显示)泄漏该内存


仅考虑到这两种选择,函数A显然更可取。它有缺点(特别是在面对多线程时),但至少在某些情况下它是正确的。函数B(目前的状态)完全错误。

忘记堆栈v。堆这不是这里发生的最重要的事情

有时
静态
修改范围,有时修改寿命。典型示例:

void int foo() {
     static int count = 0;
     return count++;
}
尝试反复调用此函数,甚至可能从几个不同的函数或文件调用,您将看到
计数不断增加,因为在这种情况下
静态
赋予变量的生存期等于整个程序执行的生存期

如果我理解正确,两个程序都会创建一个存储在堆上的整数7

不,静态变量是,并且它们在程序的整个生命周期中都有生命周期。当您使用
malloc()
分配内存时,内存是在堆中分配的,必须使用
free()
调用显式释放内存

在何种情况下,您可以使用一种方法而不是另一种方法

当您希望对同一函数的多次调用访问同一变量时,可以使用第一种方法。例如,在您的示例中,x只初始化一次,当您第二次调用该方法时,使用相同的
x
变量

当您不想为函数的多次调用共享变量时,可以使用第二种方法,以便第二次调用此函数,再次调用x
malloc
ed。 每次都必须释放x

对于每种类型的
f()

结果会有所不同


静态变量在main()之前创建,运行程序后不需要分配内存。

首先,static是一个存储类,malloc()是一个API,它触发brk()系统调用来分配堆上的内存

如果我理解正确,两个程序都会创建一个整数 7是存储在堆上的吗

否。静态变量存储在分配给程序的内存的数据部分。即使静态变量的作用域结束,仍然可以在其作用域之外访问它,这可能表明数据段的内容具有与作用域无关的生存期

在何种情况下,您可以使用一种方法而不是另一种方法

如果您希望在给定范围内对内存进行更多控制,请使用
malloc()/free()
,否则更简单(更干净)的方法是使用静态

就性能而言,声明一个静态变量要比在堆上分配它快得多。由于堆管理的算法很复杂,并且为堆请求提供服务所需的时间因算法类型而异


我可以考虑建议使用静态的另一个原因是,静态变量默认初始化为零,因此更不用担心。

考虑下面的示例,以了解静态是如何工作的。通常我们使用static关键字来定义变量或函数的范围。e、 g.定义为静态的变量将被限制在函数内,并将零售其值

但如下面的示例程序所示,如果您将静态变量的引用传递给
...
f();
f();
...

f(){
    static int x = 7;
    printf("x is : %d", x++);
}

f(){
   int *x = malloc(sizeof(int));
   if (x != NULL)
      *x = 7; 
   printf("x is : %d", (*x)++);
   free(x);   //never forget this,
}
#include <stdio.h>

void f2(int *j)
{
    (*j)++;
    printf("%d\n", *j);
}

void f1()
{   
    static int i = 10;
    printf("%d\n", i);
    f2(&i);
    printf("%d\n", i);  
}

int main()
{
    f1();       
    return 0;   
}