Ошибка bad_alloc при реализации функции изменения размера вектора
Я пытаюсь реализовать функцию изменения размера вектора в C++. Я думаю, что справился с каждой ситуацией, но все еще получаю ошибку bad_alloc. Три случая в этой реализации изменения размера: 1) когда new_size меньше, чем old_size(в моем коде, size); 2) когда new_size больше размера, но меньше емкости; 3) случай 3: когда новый _size больше емкости
void Vector::resize(int new_size)
{
//if the new_size is smaller, make the size smaller, don't need to worry about memory
//the content is reduced to its first n element
//remove those beyond and destroy them
if(new_size < size){
for(int i = size-1; i > new_size; i--){
erase(i);
}
size = new_size;
}
//if the new_size is bigger
//case 1: new_size is smaller than capacity
//inserting at the end of as many elements as needed
if(new_size > size && new_size < capacity){
for(int i=size; i < new_size; i++){
insert(i, 0.0);
}
size = new_size;
}
//case 2: new_size is greater than capacity
//increase the capacity of the container
//increase the capacity to new_size
double *tmp_data = new double(new_size);
//transfer data to tmp_data
for(int i=0; i < size; i++)
{
tmp_data[i] = data[i];
}
data = tmp_data;
delete [] data;
size = new_size;
capacity = new_size;
}
2 ответа
Есть несколько вещей не так с этим кодом. Тот, который выскакивает первым:
//increase the capacity to new_size
double *tmp_data = new double(new_size);
Вы намереваетесь выделить массив, но на самом деле выделяете один double
, Вы имели в виду:
double *tmp_data = new double[new_size];
Хотя, как только вы это исправите...
data = tmp_data;
delete [] data;
Вы хотите сделать это в обратном порядке, иначе вы оставите себя с удаленным участником.
И как только вы это исправите, вы хотите return
из ваших дел рано. У вас есть три случая (а не два, как подсказывают ваши комментарии), и вы хотите перераспределить только в том случае, если вам это действительно нужно (например, дело № 3). Как есть, вы перераспределяете во всех ваших случаях.
Как указал Барри, в оригинале было несколько ошибок.
Вот ваш код с несколькими предложениями:
void Vector::resize(int new_size)
{
if(new_size <= size) { // use "<=" here
// if you are dealing with doubles, what is there to erase?
// (I would remove that loop)
for(int i = size-1; i > new_size; i--){
erase(i);
}
size = new_size;
return; // you're done here, you can return
}
if(new_size <= capacity) { // again "<=", if you return, then no need for anything more
// "insert()" sounds confusing, you're doing a set() here
for(int i=size; i < new_size; i++){
insert(i, 0.0);
}
size = new_size;
return; // again, you can now return, you're done
}
double *tmp_data = new double(new_size);
// you could use std::copy() here
for(int i=0; i < size; i++)
{
tmp_data[i] = data[i];
}
// as indicated by Barry, you could inverse these
delete [] data;
data = tmp_data;
size = new_size;
capacity = new_size;
}
Я удалил все ваши комментарии и выложил свои для ознакомления.
Другой способ справиться с тремя подобными случаями - использовать ключевое слово else следующим образом:
if(new_size <= size) {
...
} else if(new_size <= capacity) {
...
} else {
...
}
И чтобы было понятно, у вас может быть три подфункции, которые вы вызываете из каждой
...
случаи. Таким образом, вы видите основную логику вашего
resize()
функция.