删除数组只会偶尔失败

时间:2017-10-19 10:06:03

标签: c++ arrays pointers

我正在学习C ++中的指针,遇到了一个非常奇怪的问题。我们的任务是为我们自己的类编写自己的push_back函数,该函数包含一个整数数组。

我有以下简单的功能:

void IntRow::push_back(int value){
    int *elements_temp = new int[size+1];
    for (int i = 0; i <= size; i++){
        elements_temp[i] = elements[i];
    }
    elements_temp[size + 1] = value;
    elements = new int[size+1];
    for (int i = 0; i <= size+1; i++){
        elements[i] = elements_temp[i];
    }
    delete [] elements_temp;
    size++;
}

然而,这就失败了,但仅限于某些delete [] elements_temp;

出现以下错误消息:

incorrect checksum for freed object - object was probably modified after being freed.

为什么会发生这种情况,为什么只会发生有时

P.S。:我实际上是否必须释放elements_temp或者在函数存在后它是否已被释放?

2 个答案:

答案 0 :(得分:5)

当您访问数组边界外的元素时,elements_temp[size + 1] = value;的行为未定义。

这种未定义的行为表现为偶尔的程序崩溃。

是的,您需要在delete[]返回的指针上明确地调用new[]。 (出于兴趣,谁在delete[]上致电elements?)

或者,使用std::vector<int>

答案 1 :(得分:1)

int *elements_temp = new int[size+1];
for (int i = 0; i <= size; i++){
    elements_temp[i] = elements[i];
}
elements_temp[size + 1] = value;

您已分配elements_temp来存储size+1个整数。此数组中的有效索引从0size size+1),因为索引在C ++中基于0。 所以,你在外面上面的最后一行写了数组边界。这是undefined behavior,这可能是导致问题的原因。

您可能想要的是为size+1整数分配空间,并将先前的整数复制到新数组,然后添加最后一个新元素:

// Allocate room for size+1 integers:
const int newSize = size + 1; 
int* elements_temp = new int[newSize];

// Copy the old array data to the new array.
// Note: i < size, *not* <= !
for (int i = 0; i < size; i++) {
    elements_temp[i] = elements[i];
}

// Write the new item at the end of the array.
// Note: The index is "size", *not* "size+1"
elements_temp[size] = value;

// Update the size data member in your array class to store the new size
size = newSize;

此外,在分配新创建的数组之前,您应delete elements数组,例如:

// Get rid of old array memory
delete[] elements;

// If you don't call delete[] above, you will *leak* the old elements array

// Take ownership of the new array
elements = elements_temp;

更好的分配政策

我想补充一点,每次向其中添加项目时分配 new 数组都是一种非常低效的策略。更好的方法(例如由标准std::vector容器使用)是预先分配一些内存 ,创建一种可用的容量,然后分配一个< em> new 数组并将旧数据复制到新数组,仅当旧向量没有空间时(换句话说,只有当没有更多“容量”可用时)。

事实上,new[]的动态内存分配很昂贵,最好将它们最小化。 (虽然在此学习过程中,这种能力优化可能是您的老师想要的,也可能不是。)