C语言 使用 calloc 和释放分配内存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4311868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:14:50  来源:igfitidea点击:

allocating memory using calloc and freeing

cmallocfree

提问by ant2009

gcc 4.4.4 c89

海湾合作委员会 4.4.4 c89

I have a program that I am testing. I create a struct object called devname and allocate memory so that I can fill the elements. I display them and then free the memory that was allocated.

我有一个正在测试的程序。我创建了一个名为 devname 的结构对象并分配内存,以便我可以填充元素。我显示它们,然后释放分配的内存。

However, I am getting the following error:

但是,我收到以下错误:

invalid operands to binary != (have ‘struct Devices_names' and ‘void *')

That is in my for loop for displaying the structure elements. However, I feel I am testing for a NULL pointer.

那是在我的 for 循环中用于显示结构元素。但是,我觉得我正在测试 NULL 指针。

Just a further question, is there an problem with the free?

还有一个问题,免费有问题吗?

Many thanks for any advice,

非常感谢您的任何建议,

#include <stdio.h>
#include <stdlib.h>

static struct Devices_names {
#define MAX_NAME_LEN 80
    int id;
    char name[MAX_NAME_LEN];
} *devname;

static void g_create_device_names(size_t devices);
static void g_get_device_names();
static void destroy_devices();

int main(void)
{
#define DEVICES 5
    g_create_device_names(DEVICES);

    g_get_device_names();

    destroy_devices();

    return 0;
}

static void g_create_device_names(size_t devices)
{
    size_t i = 0;
    devname = calloc(devices, sizeof *devname);
    if(devname == NULL) {
        exit(0);
    }

    for(i = 0; i < devices; i++) {
        devname[i].id = i;
        sprintf(devname[i].name, "device: %d", i);
    }
}

static void g_get_device_names()
{
    size_t i = 0;

    for(i = 0; devname[i] != NULL; i++) { <-- ERROR HERE
        printf("Device id --- [ %d ]\n", devname[i].id);
        printf("Device name - [ %s ]\n", devname[i].name);
    }
}

static void destroy_devices()
{
    while(devname != NULL) {
        free(devname++);
    }
}

回答by Justin Spahr-Summers

Since you only have one allocation to create the whole devnamearray, you only need to check that array for NULL, and only need to free that one array. As you're looking through devname, each entry is actually a struct Devices_names, not a pointer, so it can't be compared with NULLor freed in any meaningful way. In this case, you will need a separate variable that tracks how manyentries there are:

由于您只有一个分配来创建整个devname数组,因此您只需检查该数组中的NULL,并且只需要释放该数组。当您查看 时devname,每个条目实际上是一个struct Devices_names,而不是一个指针,因此无法NULL以任何有意义的方式进行比较或释放。在这种情况下,您将需要一个单独的变量来跟踪有多少条目:

for (i = 0; i < devname_count; i++) {
    printf("Device id --- [ %d ]\n", devname[i].id);
    printf("Device name - [ %s ]\n", devname[i].name);
}

...

free(devname);
devname = NULL;
devname_count = 0;

回答by ?imon Tóth

devname[i]is not a pointer its a struct Devices_names, therefore the comparison doesn't make sense.

devname[i]不是指针 a struct Devices_names,因此比较没有意义。

回答by Simone

Where you write:

你在哪里写:

for(i = 0; devname[i] != NULL; i++) { <-- ERROR HERE

you are testing against NULL an instance of Device_names, not a pointer. It would be fine if you had an array of pointers to Device_names.

您正在针对 NULL 测试 Device_names 的实例,而不是指针。如果你有一个指向 Device_names 的指针数组就好了。

The other problem is that you are allocating only one Device_names, so you have not an array of them.

另一个问题是您只分配了一个 Device_names,因此您没有它们的数组。

回答by Vovanium

After callocyou need only test for returned pointer to be not-null (and calloccall succeeded).

calloc您只需要测试返回的指针是否为非空(并且calloc调用成功)之后。

But once you callocated an array you cannot determine how many items in allocation having only pointer to it, so neither devname[i] != NULL, nor devname+i != NULLwill not work, altough second will compile. Only environment or RTL know this. And this is great difference between *allocallocation and static declaration (even it is of variable size as introduced in C99). So you NEED to store size of allocated array elsewhere.

但是一旦你定义calloc了一个数组,你就无法确定分配中有多少项只有指向它的指针,所以既不会devname[i] != NULL,也devname+i != NULL不会工作,尽管第二个会编译。只有环境或 RTL 知道这一点。这是*alloc分配和静态声明之间的巨大区别(即使它是 C99 中引入的可变大小)。所以你需要在别处存储分配数组的大小。

Also remember, array (or any other memory chunk) allocated with single calloc()should be deallocated with single free()call with SAME pointer as returned by malloc. Passing any other pointer to free()cause undefined behaviaour (which is often FAIL).

还请记住,使用 single 分配的数组(或任何其他内存块)calloc()应该free()通过使用 malloc 返回的 SAME 指针的single调用解除分配。传递任何其他指针会free()导致未定义的行为(通常是 FAIL)。

So your code should be:

所以你的代码应该是:

static struct Devices_names {
#define MAX_NAME_LEN 80
    int id;
    char name[MAX_NAME_LEN];
} *devname;
size_t devicecount;

...

    devname = calloc(devices, sizeof *devname);
    if(devname == NULL) {
        exit(0);
    }
    devicecount = devices;

...

    for(i = 0; i<devicecount; i++) { // <-- no error more here

...

static void destroy_devices()
{
    free(devname);
}