简体   繁体   English

从结构的动态数组中删除元素

[英]Remove element from dynamic array of structure

I'm working in C我在 C 工作

I have a struct called Entity and I create a dynamic array of that struct.我有一个名为 Entity 的结构,我创建了该结构的动态数组。 Then I try to remove one element from the array but I don't get the behaviour I want.然后我尝试从数组中删除一个元素,但我没有得到我想要的行为。

Here is the code I'm using:这是我正在使用的代码:

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

typedef struct Entity
{
    int x, y;
    int velX, velY;
}Entity;

int remove_element(Entity** array, int sizeOfArray, int indexToRemove)
{
    int i;

    printf("Beginning processing. Array is currently: ");
    for (i = 0; i < sizeOfArray; ++i)
        printf("%d ", (*array)[i].x);
    printf("\n");

    Entity* temp = malloc((sizeOfArray - 1) * sizeof(Entity)); // allocate an array with a size 1 less than the current one

    memmove(
            temp,
            *array,
            (indexToRemove+1)*sizeof(Entity)); // copy everything BEFORE the index

    memmove(
            temp+indexToRemove,
            (*array)+(indexToRemove+1),
            (sizeOfArray - indexToRemove)*sizeof(Entity)); // copy everything AFTER the index


    printf("Processing done. Array is currently: ");
    for (i = 0; i < sizeOfArray - 1; ++i)
        printf("%d ", (temp)[i].x);
    printf("\n");

    free (*array);
    *array = temp;
    return 0;

}

int main()
{
    int i;
    int howMany = 20;

    Entity* test = malloc(howMany * sizeof(Entity*));

    for (i = 0; i < howMany; ++i)
        (test[i].x) = i;

    remove_element(&test, howMany, 14);
    --howMany;

    return 0;
}

And the output I get :我得到的输出:

Beginning processing. Array is currently: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Processing done. Array is currently: 0 1 2 3 4 1866386284 6 7 8 9 10 11 12 13 15 16 17 18 19

Then the program crashes at the free (*array);然后程序在free (*array);处崩溃free (*array); line.线。 I want my second line to be 0 1 2 3 4 5 6 7 8 9 10 11 12 13 15 16 17 18 19.我希望我的第二行是 0 1 2 3 4 5 6 7 8 9 10 11 12 13 15 16 17 18 19。

How could I solve my problem ?我怎么能解决我的问题?

First thing you have allocated memory space for holding 20 Enity* .您首先分配了用于保存 20 Enity*内存空间。 Then you have dereferenced it (and the value it contained is indeterminate).然后您取消了它的引用(并且它包含的值是不确定的)。 This is undefined behavior .这是未定义的行为 And all story ends here.而所有的故事到此结束。

But let's analyze what you mostly wanted.但是让我们分析一下您最想要的东西。

Entity* test = malloc(howMany * sizeof(Entity));
                                       ^^^^^^^

is what you wanted.是你想要的。 Because only if you do this you will get the member elements x and so on.因为只有这样做,你才会得到成员元素x等等。

Also if you are considering 0 indexing then the memmove calls should be此外,如果您正在考虑0索引,那么memmove调用应该是

memmove(temp, *array, (indexToRemove)*sizeof(Entity)); 
memmove(temp+indexToRemove, (*array)+(indexToRemove+1), 
            (sizeOfArray - indexToRemove - 1)*sizeof(Entity)); 

These two changes will be enough to solve the problems you are facing and realizing the correct behavior.这两个变化将足以解决您面临的问题并实现正确的行为。 (If this is all there is in your code). (如果这就是您的代码中的全部内容)。

Also as per standard the main() should be declared like this in case it doesn't take any parameter int main(void) .同样按照标准, main()应该像这样声明,以防它不接受任何参数int main(void) Free the dynamically allocated memory when you are done working with it.使用完毕后释放动态分配的内存。 Also you should check the return value of malloc - in case it fails it returns NULL and you should handle that case.此外,您应该检查malloc的返回值 - 如果它失败,则返回NULL ,您应该处理这种情况。

Your offset calculations are off by one in both memmove instances.您的偏移量计算在两个memmove实例中都memmove Use this instead:改用这个:

// copy everything BEFORE the index
memmove(temp,
        *array,
        indexToRemove * sizeof(Entity));

// copy everything AFTER the index
memmove(temp + indexToRemove,
        *array + indexToRemove + 1,
        (sizeOfArray - indexToRemove - 1) * sizeof(Entity));

在 main 本身,你的内存分配没有正确完成。如果你使用双指针,你应该首先为双指针分配内存,然后在循环中一一分配单指针。

a little touch一点点接触

remove element in any type of struct array删除任何类型的结构数组中的元素

regards问候

int remove_element(void **input_ptr, int input_size, int index_remove, int struct_size)
{
    void *temp_ptr;

    temp_ptr = malloc((input_size - 1) * struct_size);
    if (temp_ptr == 0)
        return -1;

    memmove(temp_ptr, *input_ptr, index_remove * struct_size);

    memmove(temp_ptr + (index_remove * struct_size), (*input_ptr) + (index_remove + 1) * struct_size, (input_size - index_remove - 1) * struct_size);

    free(*input_ptr);

    *input_ptr = temp_ptr;

    return 1;
}

usage example for question struct问题结构的使用示例

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

typedef struct Entity
{
    int x, y;
    int velX, velY;
}Entity;

int remove_element(void **input_ptr, int input_size, int index_remove, int struct_size)
{
    void *temp_ptr;

    temp_ptr = malloc((input_size - 1) * struct_size);
    if (temp_ptr == 0)
        return -1;

    memmove(temp_ptr, *input_ptr, index_remove * struct_size);

    memmove(temp_ptr + (index_remove * struct_size), (*input_ptr) + (index_remove + 1) * struct_size, (input_size - index_remove - 1) * struct_size);

    free(*input_ptr);

    *input_ptr = temp_ptr;

    return 1;
}

int main()
{
    int i;
    int howMany = 20;

    Entity* test = malloc(howMany * sizeof(Entity));

    for (i = 0; i < howMany; ++i)
    {
        (test[i].x) = i;
        printf("test[%d].x = '%d'\n", i, test[i].x);
    }

    remove_element((void**)&test, howMany, 14, sizeof(Entity));
    --howMany;

    printf("Deleted index --- new array\n");
    for (i = 0; i < howMany; ++i)
        printf("test[%d].x = '%d'\n", i, test[i].x);

    return 0;
}

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

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