如何使用 Memmove 和 Memset 删除列表中的项目?

How Would I Use Memmove and Memset to Remove an Item In My List?

我正在尝试从列表中删除一个项目。我不知道如何使用 memset 和 memmove 来做到这一点。我想要它的例子:

初始数组:

  1. 测试1 1公斤
  2. 测试2 2公斤
  3. test3 3公斤
  4. test4 4公斤
  5. 测试5 5公斤

删除第 2 项后:

  1. 测试1 1公斤
  2. test3 3公斤
  3. test4 4公斤
  4. 测试5 5公斤

我的代码:

#define NameLength 20
#define UnitLenght 10
#define SpaceName 5

struct object
{
    char name[NameLength];
    float amount;
    char unit[UnitLenght];
};
struct inventory
{
    struct object *add;
    int nrOfobject;
};

void allocateMemory(struct inventory *allItem);
void addItems(struct inventory *allItem);//Adding an item makes nrOfobject +1
void removeOneItem(struct inventory *allItem);//based on the answer from @Bodo

int main(void)
{
    struct inventory shopping = {NULL, 0};
    int choice;
    printf("\nWelcome to the shopping list manager.\n");
    do
    {
        printf("\n1 - add grocery");
        printf("\n2 - remove grocery from list");
        scanf("%d", &choice);
        while(getchar() != '\n');

        switch (choice)
        {
        case 1:
            allocateMemory(&shopping);
            if (shopping.add == NULL)
                break;
            addItems(&shopping);
            break;

        case 2:
            removeOneItem(&shopping);
            break;

void allocateMemory(struct inventory *allItem)
{
    struct object *tempurary;
    if (allItem->nrOfobject == 0)
        tempurary = (struct object *)calloc(1, sizeof(*tempurary));
    else
        tempurary = (struct object *)realloc(allItem->add, sizeof(*tempurary)*(allItem->nrOfobject +1));

    allItem->add = tempurary;

}

void removeOneItem(struct inventory *allItem) 
{
    int t;
    printf("\nWhich item do you want to remove? ");
    scanf("%d", &t);

        memmove(&allItem->add[t-1], &allItem->add[t], (allItem->nrOfobject-t)*sizeof(*allItem->add));
        allItem->nrOfobject--;
        struct object *tempurary;
        tempurary = realloc(allItem->add, sizeof(*tempurary)*(allItem->nrOfobject));
        allItem->add = tempurary;
    
}

添加了代码,对名称进行了细微更改,以及我如何重构我的代码,nrOfItemsAddednrOfobject 相同。 添加到问题中,因为这是一个非常古老的问题。我不是在寻找如何在代码中做到这一点,特别是我将如何应用这个概念。 @Bodo 的回答正是我想要的,只是一些提示和逻辑帮助。

此答案仅供参考,并非完整解决方案。

如果你想删除item 2,你可以简单地从item 3的地址移动数据,大小为3个item (3..5) 使用 memmove.

项目 2 的地址

本次递减后 nrOfItemsAdded

您可以选择 realloc() 将内存调小。

如果您减少分配的大小,您可以选择使用memset清除[=的(旧)地址处的1个元素的内存32=]项目 5。这并不是真正必要的,因为 nrOfItemsAdded 告诉你这个元素未被使用,内存将在下一次调用 addItems.

时被覆盖

编辑:

此答案包含对 original version of the question 中显示的代码中的函数和变量的引用。不幸的是,代码被完全删除,而不是创建一个最小的可重现示例。
现在添加了一些不完整的代码,甚至包含基于此答案的解决方案。 要理解此答案,建议参考 original code.