繁体   English   中英

为什么我们需要calloc(或malloc)?

[英]Why do we need calloc (or malloc)?

在我整个CS职业生涯中忽略了C后,我决定试一试!

在初始化变量时,我们可以:

int b = 0;

这初始化b,为它分配内存,我们以后可以用它来更新它

b = 2;

如果需要的话。

所以,原谅我这个荒谬的“noob”问题,但为什么我们需要这样的电话:

double *b = (double *) calloc(n, sizeof(double));

初始化变量时会为它分配空间吗?

为什么我们不能这样做

double b = 0;
b* = b.addressOf(b) //or some similar construct.

有什么用?

我试过谷歌这个无济于事所以请原谅我 - 不幸的是*在谷歌是一个通配符,因此很难找到相关的结果。

在当前上下文中声明的变量在上下文结束时终止它们的生命周期。

分配内存为您提供了存储寿命较长变量的空间。

例如,

double *foo() {
    double d;
    return &d;
}

void bar() {
    double *d = foo();
    *d = 0.0;
}

将尝试访问不再存在的变量,因为它的生命周期是foo函数。

C和C ++不跟踪对象。 指针只指向对象,但不延长对象的生命周期,因此即使指针不是NULL指针也完全有效。

但是,这是有效的:

double *foo() {
    return (double *)malloc(sizeof(double));
}

void bar() {
    double *d = foo();
    *d = 0.0;
}

这将为double分配内存,并将指针返回到内存,该内存在使用free函数显式返回池之前保持有效。 不将其返回池将导致内存泄漏。

除非我完全弄错,否则在C中, callocmalloc是实现动态数据结构的唯一可能性。

当涉及变量分配时,您可以这样做:

  1. 静态地在栈上,简单地说: int a = 10 这些变量在堆栈上定义,最有可能与使用它们的一些代码一起定义(这就是为什么在没有正确检查boudadries的情况下写入堆栈中声明的数组可能会很危险。您可能会覆盖代码)。 变量还有一个范围:函数范围,全局范围和其他范围(例如if-else的if-branch)。 它们使用起来很快,但它们或多或少都是静态的,并且它们具有您不需要清洁它们的巨大优势。 它们由应用程序自动清理。 但是它们有很大的缺点。 堆栈空间比堆空间更有限。 因此,您只能使用适度大小的变量(不要从字面上理解,而是对您的操作系统允许的内容进行一些研究。对所有人来说,64KB是不够的:))。
  2. 动态地在堆上,使用calloc()或其他一些内存分配函数。 这些变量在称为堆或动态内存的区域中声明。 这些变量将保留在那里,直到使用它们的应用程序退出(在这种情况下(现代)操作系统通常将内存回收到自身),或者它们使用free() free使用。 你总是应该释放内存以避免内存泄漏。 动态内存的优势在于(在现代操作系统上)可寻址内存远大于分配给堆栈空间的大小,因此您可以拥有更多,更大,更大的结构和数组。

范围是可以访问变量的代码的区域或部分。 可以有

  1. 文件范围
  2. 功能范围
  3. 块范围
  4. 计划范围
  5. 原型范围

#include<stdio.h>

void function1()
{
    printf("In function1\n");
}

static void function2()
{
    printf("In function2\n");
    {
        int i = 100;
Label1: 
        printf("The value of i =%d\n",i);
        i++;
        if(i<105)
        goto Label1;
    }
}

void function3(int x, int y);

int main(void) 
{
    function1();
    function2();
    return 0;
}

在这个例子中,

  • 'function1()'有'程序范围'。
  • 'function2()'有'文件范围'。
  • 'Label1'具有'功能范围'。 (标签名称在函数中必须是唯一的。“标签”是唯一具有功能范围的标识符。
  • 变量'i'具有'块范围'。
  • 变量'x'和'y'具有'原型范围'。 函数参数列表中不能有两个名称为“x”或“y”的变量。

上例中的变量i具有块范围。 如果控件超出范围(生命结束),则变量消失。 您无法访问该变量。

所以C提供动态内存构造来访问这种场景中的内存。 例如:

int* function(void)
{
    int *ptr  = malloc(sizeof(int));
    *ptr = 5;
    return ptr;
}

int main(void)
{
    printf("%d", function());
    return 0;
}

即使变量ptr超出范围, printf仍会打印该值,但ptr指向的内存仍然存在(有生命)。

另请阅读https://stackoverflow.com/a/18479996/1814023

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM