如何从C中删除数组中的项?

时间:2013-10-29 22:18:31

标签: c arrays pointers structure

我想从b->数组中删除元素,如下面的代码所示: removeItem 函数 我试图从b-> array = {11.11,12.12,13.13}删除12.12,但它导致分段错误而不是打印{11.11,13.13}。任何人都可以帮忙摆脱它吗?

typedef struct
{
  float val;
}data;

typedef struct
{
  data **array;
  int size;
}bag;
int main(int argc,char* argv[])
{

    bag *str = createBag(); 
    #ifdef DEBUG
    printf("Inital values: %p %d\n",str->array,str->size);
    #endif
    data *iptr = createData(10.10);
    data *iptr1 = createData(11.11);
    data *iptr2 = createData(12.12);
    data *iptr3 = createData(13.13);
    data *iptr4 = createData(14.14);
    #ifdef DEBUG
    printf("%f\n",iptr->val);
    #endif
    addData(str,iptr);
    addData(str,iptr1);
    addData(str,iptr2);
    addData(str,iptr3);
    addData(str,iptr4);
    printBag(str);
    data *ptr = getData(str,4);
    printf("Data item 4 is:%f\n",ptr->val);
    int b = getBagSize(str);
    printf("Size of bag: %d\n",b);
    removeBack(str);
    printBag(str);
    removeFront(str);
    printBag(str);
    //cleanBag(str);
    int s = searchBag(str,10.10);
    printf("%d\n",s);
    removeItem(str,12.12);
    printBag(str);
  return 0;
}


bag* createBag()
{
    bag *str = (bag*)malloc(sizeof(bag));
    str->array = NULL;
    str->size = 0;
    return str;
}

data* createData(float v)
{
    data *iptr = (data*)malloc(sizeof(data));
    iptr->val = v;
    return iptr;
}

void addData(bag* b, data* d)
{
    b->size++;

    data** array1 = (data**)malloc(sizeof(data*)* b->size);



    if(b->array!= NULL)
    {
        int i;
        for(i = 0; i<b->size;i++)
        {
            array1[i] = b->array[i];
        }
    }

    free(b->array);
    array1[b->size-1] = d;

    b->array = array1;

}

void printBag(bag *b)
{
    int i;
    for(i=0; i<b->size;i++)
    {
        printf("%f\n",b->array[i]->val);
    }
}

data* getData(bag *b, int pos)
{

    if(pos>5)
    {
        printf("change array position\n");
    }   
    return b->array[pos];


}

int getBagSize(bag *b)
{
    return b->size;

}

void removeBack(bag *b)
{
    b->size--;
    free(b->array[b->size]);

    data **array2 = (data**)malloc(sizeof(data*)* b->size);

    if(b->array!= NULL)
    {
        int i;
        for(i = 0; i<b->size;i++)
        {
            array2[i] = b->array[i];
            #ifdef DEBUG
            printf("%f\n",array2[i]->val);
            #endif
        }

    free(b->array);
    b->array = array2;
    }
}

void removeFront(bag *b)
{
    b->size--;
    free(b->array[0]);

    data **array2 = (data**)malloc(sizeof(data*)* b->size);

    if(b->array!= NULL)
    {
        int i;
        for(i = 0; i<b->size;i++)
        {
            array2[i] = b->array[i+1];
            #ifdef DEBUG
            printf("%f\n",array2[i]->val);
            #endif
        }

    free(b->array);
    b->array = array2;
    }

}
/*void cleanBag(bag *b)
{
    int i;
    for(i=0;i<b->size;i++)  
    {
        free(b->array[i]);
    }
    free(b->array);
    free(b);        
}*/

int searchBag(bag *b,float v)
{
    int i;
    for(i=0;i<b->size;i++)
    {

        if(b->array[i]->val==v)
        {
            return (i+1);
        }
    }
    return -1;
}

void removeItem(bag *b, float v)
{
    int flag = 0,i = 0;

    flag = searchBag(b,v); 
    if(flag != -1) 
    { 
        data **array2 = (data**)malloc(sizeof(data*)*(b->size-1));

        for(i = 0; i < (b->size); i++) 
        { 
             if(i == (flag-1))
            { 
                i = i + 1;
                continue; 
            } 

            array2[i] = b->array[i]; 
        } 
        free(b->array); 
        b->size--; 
        b->array = array2; 
    } 
    else 
    {
        printf("Element is not found\n");
    }
}

1 个答案:

答案 0 :(得分:0)

您的代码中存在两个错误。

  1. searchBag 如果在包中找不到浮点值,则返回0。 但是,if(flag != -1)的函数 removeItem 测试。它应该测试if(flag != 0)

  2. seg的原因。您遇到的错误还在于 removeItem 功能。 请注意为 array2 分配的内存仅用于b-&gt; size-1元素。此数组的有效数组索引范围为0 ... b-> size-2 。 现在,看看for循环,你会注意到索引变量i将从0运行到 b-&gt; size-1 。在最后一次迭代中,我将变为b-&gt; size-1,因此代码会尝试在超出分配的array2内存的位置array2[b->size-1]处写入。


  3. removeItem 函数的可能修复方式如下所示:

    void removeItem(bag *b, float v)
    {
        int flag = 0;
        int oldArrayIndex = 0;
        int newArrayIndex = 0;
    
        flag = searchBag(b,v); 
        if(flag != 0) 
        { 
            data **array2 = (data**) malloc(sizeof(data*)*(b->size-1));
    
            for(oldArrayIndex = 0; oldArrayIndex < (b->size); oldArrayIndex++) 
            { 
                if(oldArrayIndex != (flag-1))
                { 
                    array2[newArrayIndex] = b->array[oldArrayIndex]; 
                    newArrayIndex++;
                } 
            } 
            free(b->array); 
            b->size--; 
            b->array = array2; 
        } 
        else 
        {
            printf("Element is not found\n");
        }
    }