2016-04-07 2 views
0

Я бы хотел изменить размер массива, когда он превышает его предел. Я создал для этого функцию.Реализация собственного realloc

void AddElemenet(int i , int value){ 

    if(i > index - 1){ 
    int tmp = index; 
    double *new_arr; 
    while(i > tmp){ 
     tmp*=2 
    } 
    new_arr = new double[tmp](); 
    for(int j = 0; j < index ; j++){ 
     new_arr[j] = arr[j]; 
    } 
    index = tmp; 
    delete[] arr; 
    arr = new_arr; 
    } 
    arr[i] = value; 

} 

индекс относится к максимальному размеру массива; а arr - динамически распределенный массив с использованием самого new. Проблема в том, что я назначаю arr локальной переменной, которая уничтожается. Я попробовал присваивать его как refference или pointer, используя *arr=*new_arr

но ничего не работало до сих пор. Как я могу изменить массив, используя эту локальную переменную?

+0

является 'arr' массив? или указатель? – vu1p3n0x

+0

его динамически распределенный массив с использованием нового. Я добавлю его в вопрос. – user3706129

+3

Я не вижу в этом ничего плохого (помимо использования 'new' и' delete' в C++, это другая проблема). 'arr' указывает на вновь выделенный массив (который указывает' new_arr'). – Kevin

ответ

4

Различные ошибки в вашей реализации демонстрируют, почему почти всегда полезно использовать стандартную библиотеку. Было бы очень легко приспособить std::vector к этому интерфейсу.

Суть вашей проблемы - это путаница в отношении того, что означает index. (Это страшное имя для переменной-члена.Он ничего не говорит.Например, что-то? И на самом деле это не индекс, это размер массива. По крайней мере, так оно и должно быть.)

Предположим, что ваш массив имеет 4 элемента, поэтому index - 4 (на основе предположения, что это размер массива). Теперь вы хотите AddElement(4, 42);. Условие в if(i > index - 1), безусловно, верно: i - 4, а index - 1 - 3. Таким образом, будет введен блок перераспределения. Однако, первое, что вы делаете, это tmp = index; while(i > tmp) tmp *= 2;. i не больше tmp - оба они 4 - поэтому цикл никогда не будет работать, а tmp по-прежнему будет 4. Теперь вы выделяете новый массив с четырьмя элементами, копируете существующие четыре элемента в него, «обновляете» index до 4 (его текущее значение) и удаляете старый массив. Сразу после этого вы пытаетесь установить элемент с индексом 4 на 42. Но массив имеет только четыре элемента, поэтому это неопределенное поведение.

Поскольку вы фактически не изменили размер массива или значение index, которое указывает его размер, ваша последующая попытка распечатать значения массива остановится на его фактическом размере, игнорируя значение, которое вы изменили вне (., которые могут принадлежать к каким-либо другой структуре данных, поэтому его значение не имеет смысл в любом случае) область хранения массива

Если переименовать index как size и tmp как new_size, код намного яснее, и исправление также ясно:

if (i >= size) { 
    size_t new_size = size; 
    while (i >= new_size) new_size *= 2; /* NOT > */ 
    double* new_array = new double[new_size](); 
    for (size_t j = 0; j < size; ++j) new_array[j] = array[j]; 
    array = new_array; 
    size = new_size; 
} 
array[i] = value; 

Это все было гораздо проще и менее подвержен ошибкам, если вы использовали std::vector:

class MyVector { 
    public: 
    void AddElement(size_t i, double value) { 
     if (i >= data_.size()) data_.resize(i + 1); 
     data_[i] = value; 
    } 
    /* Many implementation details omitted */ 
    private: 
    std::vector<double> data_; 
} 
0
std::vector <int> list;  

void AddElemenet(int value) 
{ 
    list.push_back (value);  
} 

Просто используйте векторные иллюстрации. Размер массива фиксирован. Размер файла является динамическим.

Смежные вопросы