0

将 ANSI C 和 gcc 与 -Wall -pedantic 一起使用

我有 struct 并且我在循环中预先填充了它的数据。稍后我将需要从中删除一条记录。假设记录号 3。如果我使用free(snode[2]);它就足够了吗?它会自动减少记录数吗?


已编辑

struct stock_data 
{
    int ticket_price;
    int stock_level;
};

typedef struct stock_node 
{
    struct stock_data * data;
} stock_node;

stock_node * snode = NULL;

for(x = 0; x < 6; x++) {
   snode = (stock_node *) realloc(snode, x+1 * sizeof(stock_node));
   if (snode == NULL) { exit(1); }

   snode[x].data = (struct stock_data *) calloc(1, sizeof(struct stock_data));

   snode[count - 1].data->ticket_price = 100;

   snode[count - 1].data->stock_level = 10;

}
4

6 回答 6

1

You cannot partially free the malloced memory; for each malloc there must be exactly one free to free the memory (and it is then freed completely). Indeed, giving free an argument other than the same pointer returned by malloc or one of the other allocating functions is undefined behaviour.

Also, malloc and free don't have any knowledge of how you use the memory, so they don't know that you've decided to put an array of struct coin in it. malloc just gives you a pointer to an area of memory large enough to hold the number of bytes you requested, how you use them is up to you.

Use a linked list of, or an array of pointers to, individually allocated structs if you need to manage them individually. That is, use a separate malloc call to allocate every element in the list or array – note that you must also free them all individually, and each exactly once.

Edit: You changed the question to show realloc instead of malloc. However, the same applies here; you can only free the pointer returned by realloc, not a part thereof, nor does free (or realloc) know that you are using the memory for an array of structs. Since you are now callocing each data individually, you can (and indeed must) free that part individually, but you cannot free part of the realloc'ed array – you need to clean it up manually after freeing the data element.

于 2013-11-10T09:54:27.837 回答
0

如果您需要这种粒度的内存管理,您可以使用链表。

于 2013-11-10T10:03:00.440 回答
0

如果我用free(temp_coin[2]);就够了吗?它会自动减少记录数吗?

当然不是。它应该怎么知道该怎么做?这是C,你必须非常明确。

正如其他人所说,free()必须专门用于malloc()ed 区域。其他一切都可能完全破坏您的流程的数据区域 - 或者,就此而言,任何事情都可能发生,因为它是未定义的行为。

例如,free()可能假设给定地址之前的位置(顺便说一句,temp_coin[2]不是地址,它是一个struct coin. 你在这里错过了一个&......)可能是分配的字节数。malloc()如果它的合作伙伴是否以这种方式定义,则这是正确的。但是,如果你给它任何其他地址,它可能会将这部分添加到空闲列表中,而只保留原始内存部分的大小。如果您释放它,则释放的“子部分”在空闲列表中存在两次。然后麻烦就开始了。

相反,您将复制要删除的项目后面的任何内容,朝着开始的方向迈出一步。然后,您将列表中的条目数调整为 1(无论您将其存储在何处),然后可能现在(但可能稍后)调整分配的内存块的大小以完全适合数据。

请注意realloc(),根据用例,减少调用频率并提前预分配所有内容可能更明智。当然,您必须在某处记录实际分配的大小。

于 2013-11-10T10:06:52.243 回答
0

You can only free() pointers returned from malloc(). If you allocate an array, struct temp_coin*, you cannot free parts of it. You have to free the whole array using free(temp_coin).

If you try to free pointers not returned by malloc(), bad things will happen like memory corruption and undefined behaviour.

于 2013-11-10T09:56:07.760 回答
0

*If I use free(temp_coin[2]); would it be enough?*

No - It is undefined behaviour. What you malloc'ed you need to free. ie. free temp_coin

Will it decrease the record count automatically?

There is no record count in the first place

PS you do not need the cast in the malloc

于 2013-11-10T09:56:20.483 回答
0

这就是我要找的。另一个帖子

我应该搜索更多。对此感到抱歉。

我假设您将以以下形式为二维数组分配内存:

int * arr = malloc(sizeof(int)*r*c);

相反,如果您逐行分配内存,则删除行的问题会简化。

int * arr[r]; /*Declaring an array of pointers*/

/逐行分配内存/

for(i=0; i<r; i++)       arr[i] = malloc(sizeof(int)*c);

....

/ row表示要删除的行/

free(arr[row]);
for(i=row; i<r-1; i++)    arr[i] = arr[i+1];
于 2013-11-10T10:31:22.537 回答