当数组缩小时是否有必要删除元素?

时间:2010-10-29 22:47:43

标签: c++ delete-operator

我是一名学生在C ++中编写一个从int数组末尾删除零的方法。数组在struct中,struct也有一个跟踪数组长度的int。

该方法从最后一个开始检查每个元素,直到它遇到第一个非零元素,并通过改变length的值将一个元素标记为“最后一个元素”。然后该方法返回到原始的“最后一个元素”,删除那些不在界限范围内的元素(零)。

如果i大于更新的数组长度,则删除数组中i元素的部分如下所示:

if (i > p->length - 1) {
  delete (p->elems + i); // free ith elem

但这条线路是错误的。删除指针,是吗?所以我的感觉是我需要恢复指向数组的指针,然后将i添加到它,这样我将拥有我想要删除的整数的内存位置。

我的直觉是错的吗?错误是否微妙?或者,我有完全错误的想法吗?我开始怀疑:我真的需要释放这些原语吗?如果它们不是原始的我需要,在那种情况下,我将如何?

2 个答案:

答案 0 :(得分:5)

我有完全错误的想法吗?

我很害怕。

如果你进行一次new[]调用来分配一个数组,那么你必须进行一次delete[]调用来释放它:

int *p = new int[10];
...
delete[] p;

如果你的数组是在一个结构中,并且你进行一次调用来分配结构,那么你必须进行一次调用以释放它:

struct Foo {
    int data[10];
};

Foo *foo = new Foo;
...
delete foo;

无法释放阵列的一部分。

int[10]数组实际上 10个整数,连续(即32位系统上的40个字节的内存,可能加上开销)。存储在数组中的整数占用了该内存 - 它们本身不是内存分配,并且不需要释放它们。

所有这一切,如果你想要一个可变长度数组:

这就是std :: vector用于

的内容
#include <vector>
#include <iostream>

struct Foo {
    std::vector<int> vec;
};

int main() {
    Foo foo;

    // no need for a separate length: the current length of the vector is
    std::cout << foo.vec.size() << "\n";

    // change the size of the vector to 10 (fills with 0)
    foo.vec.resize(10);

    // change the size of the vector to 7, discarding the last 3 elements
    foo.vec.resize(7);
}

答案 1 :(得分:3)

如果p->elems是一个指针,那么p->elems + i也是如此(假设操作是定义的,即我是整数类型) - 和p->elems + i == &p->elems[i]

无论如何,你很可能不希望(也不能)从int数组中删除int(动态或自动分配)。那是

int* ptr = new int[10];
delete &ptr[5]; // WRONG!

这是你不能做的事情。但是,如果struct包含数组的长度,您可以在更改结构包含的长度信息后将数组视为“已调整大小” - 毕竟,无法告诉指针指向的数组大小。

但是,如果您的数组是指向整数(int*[])的指针数组,并且这些指针指向动态分配的内存,那么是的,您可以删除单个项目,并且您可以按照代码(你显示的代码很少,很难准确)。