2009-12-03 42 views
0

从结构列表中,我们如何删除其中的一些结构条目。删除结构后,不应该留下任何空白空间。如何删除C中的结构条目

下面的代码是试图实现的任务,但没有奏效。

struct symtab *sp; 
    for(sp = symtab; sp < &symtab[NSYMS]; sp++) 
     if(sp->scope == scope) // delete 
     { 
      sp = sp+1; 

     } 
+2

您确定要将数据放在表格中而不是链接列表中吗?如果你想快速删除,链接列表要快得多(free()+一些指针引用)。用桌子你需要在内存中移动东西。 – Makis 2009-12-03 09:49:31

回答

2

你可以使用的memmove():

//pseudocode, not tested 
struct symtab* end = &symtab[NSYMS]; 
for(sp = symtab; sp < end; sp++) { 
    if(sp->scope == scope) { 
     memmove(sp, sp + 1, (end - sp) * sizeof(struct symtab); 
     sp++; 
     end--; 
    } 
}    

注意end是可以改变的,因为数组会成为 “短”。与该数组一起工作的其他代码只能访问缩短的区域。

+0

你是否正在复制一个太多的数组元素? – 2009-12-03 09:58:43

+0

这大多是正确的。虽然有一些小错误。解决这些问题之后,我才得以实施。 – neuromancer 2009-12-03 10:18:21

+0

最好三重检查要移动的元素的数量。当你最不期待的时候,像这样的小错误可能会导致分段错误。 – 2009-12-03 13:47:24

1

你不能做到这一点与C风格的数组(*)。最好是将它作为链表来实现,可以是任何单链或双链。 (*)如果你需要必须使用使用数组,你可以从下一个元素到你想要删除的元素执行一个移动。但是,在这种情况下,您还必须更新NSYMS的值,它看起来像是#define,不可能。

1

你可以往回穿过阵列。不过,前进或后退,就必须移动的内存量而言,删除列表开头处的元素会导致惩罚的增加。出于这个原因,首先删除阵列末尾的条目可能会略微优化性能。


struct symtab *sp; 
struct symtab *endp; // end of array pointer 

endp = symtab + NSYMS; 
for (sp = symtab + NSYMS - 1; sp >= symtab; sp--) { 
    if (sp->scope = scope) { 
     int numelems = endp - (sp + 1); 
     if (numelems > 0) { 
      memmove(sp, sp + 1, numelems); 
      endp--; // adjust end of array pointer 
     } 
    } 
} 
0

有几个选项:

  • 继续使用一个固定大小的数组,但使用定点值的关键领域,所以你知道哪些项目是未使用(如-1)。 。当您需要添加条目时,请搜索下一个未使用的插槽。这仍然受限于具有固定大小的阵列。

  • 使用memmove在其他的答案中提到。这不是非常有效。

  • 使用链表,而不是一个固定阵列的,那么你就可以轻松地(和便宜)删除条目,以及添加。

基本上,除非你是对具有严重的内存限制,一些嵌入式系统编写代码,有可能是没有充分的理由把一个任意上限阵列上。其他结构(例如链接列表)可以很容易地添加或删除,并且周围有大量的库提供这样的容器。

而经过了这一切,你肯定不希望一个哈希表(或字典),如果你管理一个符号表?

0

该最佳解决方案是使用含有结构链表。如上所述,这对数组来说效率非常低,因为如果最后没有删除数据,就必须移动数据。