我已经看到了类似问题的其他答案,但似乎没有一个对我有用。假设我有一个动态数组:
int* myarray;
myarray = malloc(myarray, 4*sizeof(int));
myarray[0] = 1;
myarray[1] = 2;
myarray[2] = 3;
myarray[3] = 4;
我想要做的是删除(并且免费,因为数组会越来越大)数组的第一个元素。我很清楚如果缩小,realloc它会删除数组的最后一个元素。对此有什么想法吗?这可能吗?
提前致谢!
我已经看到了类似问题的其他答案,但似乎没有一个对我有用。假设我有一个动态数组:
int* myarray;
myarray = malloc(myarray, 4*sizeof(int));
myarray[0] = 1;
myarray[1] = 2;
myarray[2] = 3;
myarray[3] = 4;
我想要做的是删除(并且免费,因为数组会越来越大)数组的第一个元素。我很清楚如果缩小,realloc它会删除数组的最后一个元素。对此有什么想法吗?这可能吗?
提前致谢!
我能想到的一种方法是做
memmove(myarray, myarray+1, 3*sizeof(int))
然后用于realloc缩小数组。我不确定在 C 中有更有效的方法可以做到这一点。
通常,无法对阵列执行“删除”操作。也许您想创建和使用链表?
C++ 有其std::vector支持这一点。它将做的是将稍后出现的元素向前移动 1 个元素。您可以实现这一点,然后再调用realloc。
如果只需要删除第一个元素,则将它们反向存储是一个明显的解决方法。
您必须将所有其他元素分流到一个。从概念上讲,它是这样的:
for( int i = 0; i < 3; i++ ) p[i] = p[i+1];
正如其他人所提到memmove的,针对移动重叠的内存段进行了优化,而不是使用上述循环。
随着阵列变大,移动数据仍然效率低下。每次添加项目时重新分配一个数组更糟糕。一般建议是不要这样做。只需跟踪您的数组有多大以及其中当前存储了多少项目。当您种植它时,将其种植大量(通常您会将其扩大一倍)。
听起来您可能想要一个循环队列,在其中预先分配数组,并且当您推入和弹出项目时,头和尾指针相互追逐。
我不认为你会在 C 中找到一种正确/干净的方法来做到这一点。C++ 作为一些这样做的图书馆,几乎所有面向 OO 的语言都可以做到这一点,但不是 C。我能想到的是移动内存,是的,调用 realloc,或者将您想要释放的位置设置为已知值,您将在内存重用策略中将其视为空。
另一种解决问题的方法是通过数组的动态实现。不知道你是否想去那里,但如果你想,这里有一些简短的例子。
由于您只保存整数,因此像这样的结构:
typedef struct DynamicArray_st{
int x;
struct DynamicArray_st *next;
}DynamicArray;
可以根据程序需要分配和释放元素。它还允许在中间、开始或结尾插入,frees 也是如此。
您将执行此操作的方式是保存指向此动态类型开头的指针,然后对其进行迭代。问题是您无法通过 [] 表示法访问数据。迭代是必要的,这使得处理时间变得更重。
除此之外,你的代码会变成这样:
DynamicArray *array = malloc(sizeof(DynamicArray)); /*Just a first element that will stay empty so your Dynamic array persists*/
array->next = NULL;
DynamicArray *aux = array;
DynamicArray *new;
for(i = 0; i<4; i++){
new = malloc(sizeof(DynamicArray));
new->next = NULL;
new->x = i+1;
aux->next = new;
aux = new;
}
在这里,您有一个结构序列,每个结构都指向下一个结构,并且内部有一个整数。如果现在你会做类似的事情:
aux = array->next; /*array points to that empty one, must be the next*/
while(aux != NULL){
printf("%d\n",aux->x);
aux = aux->next;
}
你会得到输出:
1
2
3
4
释放第一个元素很简单:
aux = array->next;
array->next = aux->next;
free(aux);
如果您尝试绘制它(结构是框,next/aux/next 是箭头),您会看到一个框的箭头勾勒出一个框 - 您想要释放的框。
希望这可以帮助。