динамически выделяемый массив С++

Я выполняю какое-то задание и застрял здесь в одном месте. Я пытаюсь написать функцию list_add(). Первая его функция — добавление значений в массив. Второй функционал для него — увеличение размера массива. Так что это работает как вектор. Хотя не знаю, правильно ли я понял. Я попытался создать новый динамически выделенный массив, который больше старого, а затем скопировать все значения в новый массив.

Это правильный подход?

Вот основной корпус

int main()
{
    const int N = 7;

    //declaring dynamic array allocation
    int* list = new int[N];

    int used = 0, a_val;
    for(int i=0;i<11;i++)
    {
        list_add(list, used, N, i);
    }

    cout << endl << "Storlek: " << N << endl << endl;
    cout << "Printar listan " << endl;
    for(int i=0;i<used;i++)
    {
        cout << list[i] << ". ";
    }

}

Вот функция

bool list_add(int *list, int& space_used, int max_size, int value)
{

    if(max_size-space_used > 0)
    {
        *(list+(max_size-space_used-1)) = value;
        space_used++;
        return true;
    }
    else
    {
        cout << "Increasing size of array!" << endl;
        int new_max_size = space_used+1;
        delete [] list;
        int *list_new = new int[new_max_size];

        for(int i=0; i<new_max_size; i++)
        {
            list_new[i] = i;
            cout << list_new[i] << ". ";
        }
        cout << endl;
        space_used++;
        list = list_new;
        return false;
    }
}

person starcorn    schedule 24.11.2009    source источник
comment
почему ваша функция возвращает логическое значение?   -  person George Godik    schedule 25.11.2009
comment
Да и нет, это школьное задание, которое я нашел в Интернете. И я просто делаю это, чтобы учиться.   -  person starcorn    schedule 25.11.2009
comment
Похоже, вы не копируете значения из исходного массива в новый массив, а удаляете старый массив и создаете новый массив с тем же именем и добавляете новые значения.   -  person ChadNC    schedule 25.11.2009
comment
Джордж, нет причин. Он может быть и недействительным.   -  person starcorn    schedule 25.11.2009


Ответы (5)


Есть четыре проблемы с реализацией вашего кода:

  1. Он не копирует элементы списка.
  2. Он не присваивает значение new_list переменной list в main
  3. Он вставляет значения сзади вперед, а не после последнего значения.
  4. max_size не обновляется. Это легко пропустить, потому что вы каждый раз увеличиваете размер массива только на единицу. Таким образом, ему нужно будет выделять каждый раз, когда добавляется значение. Если вы увеличите новый размер более чем на единицу, он все равно будет перераспределяться каждый раз.

Первую проблему можно решить, изменив цикл for в list_add так, чтобы он делал копию:

for (int i = 0; i < space_used; i++) {   // this also changed.
    list_new[i] = list[i];
    cout ...
}
// insert the new value (in the front?)
list_new[max_size-space_used-1] = value;     
delete [] list;         // Delete the list afterwards instead of earlier.

Вторую проблему можно исправить, вернув указатель на список. Измените функцию main на это:

for (int i = 0; i < 11; i++) {
    list = list_add(list, used, N, i); 
} 

Третью проблему можно исправить, изменив эту строку

list_new[max_size-space_used-1] = value;

to

list_new[space_used++] = value;

Вы также должны удалить space_used++ после этого.

Чтобы увидеть четвертую проблему, вы должны изменить эту строку

int new_max_size = space_used+1;

to

int new_max_size = space_used+3;

Он все равно будет перераспределяться каждый раз. Однако он должен перераспределять только два раза.


Это полный код:

#include <iostream>
using std::cout;
using std::endl;

int* list_add(int *list, int& space_used, int& max_size, int value) {
    if (max_size - space_used > 0) {
        list[space_used++] = value;
        return list;
    }
    else {
        cout << "Increasing size of array!" << endl;
        int new_max_size = space_used+1;

        int *list_new = new int[new_max_size];

        for (int i = 0; i < space_used; i++) {
            list_new[i] = list[i];
            cout << list_new[i] << ". ";
        }
        cout << endl;

        list_new[space_used++] = value;
        max_size=new_max_size;

        delete [] list;
        return list_new;
    }
}

int main() {
    int N = 7;

    //declaring dynamic array allocation
    int* list = new int[N];

    int used = 0, a_val;

    for (int i = 0; i < 11; i++) {
        list=list_add(list, used, N, i);
    }

    cout << endl << "Storlek: " << N << endl << endl;
    cout << "Printar listan " << endl;

    for (int i = 0; i < used; i++) {
        cout << list[i] << ". ";
    }
}
person Peter Stuifzand    schedule 25.11.2009

Одна проблема, которая бросается мне в глаза, заключается в том, что вы не меняете значение указателя вашего списка вне области действия вашей функции list_add. Вы должны внести некоторые изменения, например...

bool list_add(int *list, int& space_used, int max_size, int value)

становится

bool list_add(int **list, int& space_used, int max_size, int value)

а также

list = list_new

становится

*list = list_new

В противном случае, я думаю, вы обнаружите, что когда вы перераспределяете свой список, после возврата из list_add указатель вашего списка по-прежнему будет указывать на старое местоположение.

person Parappa    schedule 24.11.2009

У вас есть правильная идея, но реализация могла бы использовать немного «смазки локтя»

попробуй это:

держите 2 внутр.

вместимость - длина, на которую вы выделяете
размер - текущий конец массива

if capacity <= size:
   make new list( size = capacity x 2 )
   memcopy old list into new list -> if you can't memcopy, copy over the data one-by-one
   delete old list
if capacity > size:
   list[size] = value
   size++

http://www.cplusplus.com/reference/clibrary/cstring/memcpy/< /а>

person George Godik    schedule 24.11.2009
comment
это предполагает, что размер увеличивается соответствующим образом вне цикла - person George Godik; 25.11.2009
comment
Тай, я собираюсь попробовать это. - person starcorn; 25.11.2009

Я бы беспокоился об этой строке:

*(list+(max_size-space_used-1)) = value;

и этот:

list_new[i] = i;
person Aaron    schedule 24.11.2009
comment
последнюю строку я использовал для проверки, поэтому я фактически скопировал массив. Его не будет, когда он заработает - person starcorn; 25.11.2009

Многое можно сказать о знании того, как решать проблемы, но это не одна из них.

#include <vector>
#include <iostream>

int main() 
{
    std::vector<int> numbers;

    for (int i = 0; i < 11; i++) {
        numbers.push_back(i);
    }

    for (int i = 0; i < numbers.size(); i++) {
        std::cout << numbers[i] << ". ";
    }

    std::cout << "\n";
}

ОБНОВЛЕНИЕ: как показано выше в другом моем ответе его функция содержит как минимум четыре ошибки в 16 строках. Это ошибка для каждых четырех строк кода. А еще есть проблемы с дизайном кода. Например, размер массива и сам массив должны быть вместе. В противном случае вы не можете гарантировать, что функция работает.

Две проблемы в коде (2,4) могут быть решены с помощью struct, содержащего указатель массива и max_size структуры данных. Таким образом, вы должны передать две переменные вместе.

person Peter Stuifzand    schedule 24.11.2009