简体   繁体   English

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

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

After ignoring C for my entire CS career I have decided to give it a look! 在我整个CS职业生涯中忽略了C后,我决定试一试!

When initialising variables, we can have : 在初始化变量时,我们可以:

int b = 0;

This initialises b, allocates memory for it, and we can later update it with 这初始化b,为它分配内存,我们以后可以用它来更新它

b = 2;

if needs be. 如果需要的话。

So, and forgive me for this ridiculously "noob" question but why do we need calls like : 所以,原谅我这个荒谬的“noob”问题,但为什么我们需要这样的电话:

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

when initialising the variable would allocate the space for it already? 初始化变量时会为它分配空间吗?

Why can we not just do 为什么我们不能这样做

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

What is the use of this? 有什么用?

I have tried Googling this to no avail so please forgive me - ufortunately * in Google is a wildcard and so relevant results are hard to find. 我试过谷歌这个无济于事所以请原谅我 - 不幸的是*在谷歌是一个通配符,因此很难找到相关的结果。

Variables declared in the current context end their lifetime at the end of the context. 在当前上下文中声明的变量在上下文结束时终止它们的生命周期。

Allocating memory gives you space to store longer-lived variables. 分配内存为您提供了存储寿命较长变量的空间。

For example, 例如,

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

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

will try to access a variable that no longer exists, because its lifetime is the foo function. 将尝试访问不再存在的变量,因为它的生命周期是foo函数。

C and C++ do not keep track of objects. C和C ++不跟踪对象。 A pointer only points to the object, but does not extend object lifetime, so it is entirely possible for a pointer to be invalid even if it is not NULL . 指针只指向对象,但不延长对象的生命周期,因此即使指针不是NULL指针也完全有效。

However, this is valid: 但是,这是有效的:

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

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

This will allocate memory for a double , and return the pointer to the memory, which remains valid until explicitly returned to the pool using the free function. 这将为double分配内存,并将指针返回到内存,该内存在使用free函数显式返回池之前保持有效。 Not returning it to the pool will create a memory leak. 不将其返回池将导致内存泄漏。

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

When it comes about variable allocation you can do it like: 当涉及变量分配时,您可以这样做:

  1. statically on the stack, simply: int a = 10 . 静态地在栈上,简单地说: int a = 10 These variables are defined on the stack most possibly together with some of the code using them (this is why it can be dangerous to write in an array declared on the stack without proper checking the boudadries. You might overwrite code). 这些变量在堆栈上定义,最有可能与使用它们的一些代码一起定义(这就是为什么在没有正确检查boudadries的情况下写入堆栈中声明的数组可能会很危险。您可能会覆盖代码)。 The variables also have a scope: function scope, global scope, and other scopes (such as the if-branch of an if-else). 变量还有一个范围:函数范围,全局范围和其他范围(例如if-else的if-branch)。 They are fast to use, however they are more or less ... static, and they have the big advantage that you don't need to clean them. 它们使用起来很快,但它们或多或少都是静态的,并且它们具有您不需要清洁它们的巨大优势。 They are automatically cleaned by the application. 它们由应用程序自动清理。 However they have a great disadvantage. 但是它们有很大的缺点。 Stack space is more limited than heap space. 堆栈空间比堆空间更有限。 So you can use only modest sized variables (Don't take it literally, instead do some research what is allowed by your OS . 64KB is not enough to everyone :) ). 因此,您只能使用适度大小的变量(不要从字面上理解,而是对您的操作系统允许的内容进行一些研究。对所有人来说,64KB是不够的:))。
  2. Dynamically on the heap, using either calloc() or some other memory allocation function. 动态地在堆上,使用calloc()或其他一些内存分配函数。 These variables are declared in an area known as the heap, or dynamic memory. 这些变量在称为堆或动态内存的区域中声明。 These variables will stay there either until the application using them exits (in this case the (modern) OS usually reclaims the memory to itself), or they are free d using free() . 这些变量将保留在那里,直到使用它们的应用程序退出(在这种情况下(现代)操作系统通常将内存回收到自身),或者它们使用free() free使用。 You always should free the memory to avoid memory leaks. 你总是应该释放内存以避免内存泄漏。 Dynamic memory has the advantage that (on a modern OS) the addressable memory is much bigger than the size allocated to stack space so you can have more, bigger, greater structures and arrays. 动态内存的优势在于(在现代操作系统上)可寻址内存远大于分配给堆栈空间的大小,因此您可以拥有更多,更大,更大的结构和数组。

Scope is the region or section of the code where a variable can be accessed. 范围是可以访问变量的代码的区域或部分。 There can be 可以有

  1. File Scope 文件范围
  2. Function Scope 功能范围
  3. Block Scope 块范围
  4. Program Scope 计划范围
  5. Prototype Scope 原型范围

Example

#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;
}

In the example, 在这个例子中,

  • 'function1()' has 'Program Scope'. 'function1()'有'程序范围'。
  • 'function2()' has 'File Scope'. 'function2()'有'文件范围'。
  • 'Label1' has 'Function Scope'. 'Label1'具有'功能范围'。 (Label names must be unique within the functions. 'Label' is the only identifier that has function scope. (标签名称在函数中必须是唯一的。“标签”是唯一具有功能范围的标识符。
  • Variable 'i' has 'Block Scope'. 变量'i'具有'块范围'。
  • Variable 'x' and 'y' has 'Prototype Scope'. 变量'x'和'y'具有'原型范围'。 There cannot be two variables with the name 'x' or 'y' in the function parameter list. 函数参数列表中不能有两个名称为“x”或“y”的变量。

The variable i in the above example have the block scope. 上例中的变量i具有块范围。 If the control goes out of scope (life ends), then the variable is gone. 如果控件超出范围(生命结束),则变量消失。 You can not access the variable. 您无法访问该变量。

So C provides dynamic memory constructs to access the memory in these kind of scenarios. 所以C提供动态内存构造来访问这种场景中的内存。 For example: 例如:

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

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

the printf would still print the value even the variable ptr is out of scope but the memory pointed by ptr still exists (has life). 即使变量ptr超出范围, printf仍会打印该值,但ptr指向的内存仍然存在(有生命)。

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

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

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