Ошибка 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() функция.

Другие вопросы по тегам