C - 给定ADDRESS时的内存分配操作,而不是指针

时间:2015-05-04 06:38:52

标签: c pointers dynamic-memory-allocation memory-address

所以,我知道在C中你可以通过引用或值传递函数参数,但从技术上讲,一切都是按值的(因为通过引用传递的实体只是地址)。

我的问题是,如果给出一个不是指针的MEMORY ADDRESS,是否可以对该地址进行malloc / calloc操作?

这是我正在处理的一个示例:

typedef struct bucket {
    int instances;
    char *key;
    struct bucket *next;
} Bucket;

typedef struct bag {
    int key_count;
    int current_capacity;
    Bucket **buckets;
} Bag;

void init_bag (Bag *bag){...}

在这个init_bag函数中,我需要获取在其他地方声明的Bag的地址并初始化它。但是,如果我只获得包的内存地址,我不知道如何做到这一点,如:

Bag bag;
init_bag(&bag);

我之前做过类似的事情,我在init_bag函数中使用了一个指向包的指针,我在函数参数的一次解引用实体上使用了malloc(此时这是一个简单的指针指向包))和修改它的操作是标准指针操作,可以设置包的实际地址的值。这一次,我需要以我上面写的形式提供函数原型,并且它需要能够接收包的地址(不仅仅是指向包的指针)并对该地址进行适当的内存分配操作。关于在目前情况下我能做些什么的任何建议?

1 个答案:

答案 0 :(得分:2)

在您的示例中,bag的内存已经分配。当你将它定义为局部变量时:

Bag bag;

您已在本地存储中创建了一个内容未初始化的结构。因此,您的函数init_bag不应该分配内存,它应该只是初始化结构的字段,例如:

void init_bag(Bag *bag) {
    bag->key_count = 0;
    bag->current_capacity = MAX_BAG;
    bag->buckets = calloc(MAX_BAG, sizeof(*bag->buckets));
}

从此函数返回后,您有一个有效的bag:您已将有效字段填入已存在的结构中,您已通过指针访问该结构。

如果您只传递了结构,那么您将初始化一个本地结构init_bag。从init_bag返回后,此结构将丢失,并且调用函数中的bag将像以前一样未初始化。传递bag地址的原因是您可以通过指针访问bag内在调用函数中创建的init_bag对象。获取对象的地址会创建指向该对象的指针。

另一方面,您在上一段中描述的代码会导致类似这样的代码:

void new_bag(Bag **bag) {
    *bag = malloc(sizeof(**bag);

    (*bag)->key_count = 0;
    (*bag)->current_capacity = MAX_BAG;
    (*bag)->buckets = calloc(MAX_BAG, sizeof(*(*bag)->buckets));
}

你会这样称呼它:

Bag *bag;

new_bag(&bag);

此代码与第一个代码段非常相似,但它会执行其他操作。它将如上所述初始化Bag结构,但它将首先在堆上创建bag对象。如果您离开当前功能,行李仍将有效,而使用

创建行李的生命周期
Bag bag;

init_bag(&bag);

仅限于当前范围。您喜欢哪种变体(或者您是否应该同时使用这两种变体)取决于您想要如何使用该包。

(这里的整个讨论实际上是关于包的内存分配。它不是指桶的内存分配。因为你的struct请求资源,你还应该有一个清理函数来释放这些再次资源。

如果您选择使用malloc在堆上分配包,那么当您清理结构时,当然也必须释放该内存。)