2015-05-11 7 views
1

Я создал простой класс целочисленного массива:Как исправить эту утечку памяти в моем методе массива resize?

#ifndef INTARRAY_H 
#define INTARRAY_H 

class IntArray 
{ 
public: 
    // Constructors/Destructor 
    IntArray(); 
    IntArray(int size); 
    IntArray(const IntArray& rhs); 
    ~IntArray(); 

    // Methods 
    int size(); 
    void resize(int newSize); 
    void print(); 

    //Operator Overloads 
    IntArray& operator=(const IntArray& rhs); 
    int& operator[](int i); 

private: 
    // Data Members 
    int* mArray; 
    int mSize; 
}; 

#endif 

Теперь проблема заключается в способе изменения размера(). Откуда я знаю это? Потому что у меня нет проблем с каким-либо объектом, пока я не создам объект и не использую метод resize(). Когда я запускаю отладчик, Visual Studio говорит мне, что у меня есть некоторая ошибка указателя, когда она проходит через деструктор для объекта, который использует функцию изменения размера и только этот объект. Все остальные объекты проходят через деструктор. Кроме того, когда я нахожусь в отладчике, и я вникаю в то, что происходит в методе изменения размера, когда я удаляю mArray внутри, он вызывает некоторые напуганные вещи. Дело в том, что он отображает на экране точно, как это должно быть, я просто получаю сообщение об ошибке. В любом случае, это то, что мой Resize() метод, и я положил в некоторых комментариях, чтобы помочь вам понять, что я думал, что я делал, как я реализовал код:

EDIT: Добавлена ​​целый класс для людей, которые просят

#include <iostream> 
#include "IntArray.h" 
using namespace std; 

// Constructors/Destructor 
IntArray::IntArray() 
{ 
    mArray = 0; 
    mSize = 0; 
} 

IntArray::IntArray(int size) 
{ 
    mSize = size; 
    if (mSize == 0) 
     mArray = 0; 
    else 
     mArray = new int[mSize]; 
} 

IntArray::IntArray(const IntArray& rhs) 
{ 
    mArray = 0; 
    *this = rhs; 
} 

IntArray::~IntArray() 
{ 
    delete[] mArray; 
    mArray = 0; 
} 

// Methods 
int IntArray::size() 
{ 
    return mSize; 
} 

void IntArray::resize(int size, int newSize) 
{ 

    int* temp = new int[mSize]; //Create temp dynamic array to store the values 

    for (int i = 0; i < mSize; i++) //Copy values from mArray into the temp array 
    { 
     temp[i] = mArray[i]; 
    } 
    delete[] mArray; //Delete the old array 
    mArray = 0; 
    mArray = new int(newSize); //Create a new array with the new size 

    if (mSize <= newSize) //Copy the values from the temp array into the new array 
    { 
     for (int i = 0; i < mSize; i++) 
     { 
      mArray[i] = temp[i]; 
     } 
    } 
    else 
    { 
     for (int i = 0; i < newSize; i++) 
     { 
      mArray[i] = temp[i]; 
     } 
    } 
    delete[] temp; //Delete the temp array 
} //Doesn't work :(

void IntArray::print() 
{ 
    //cout << 
} 

// Operator Overloads 
IntArray& IntArray::operator=(const IntArray& rhs) 
{ 
    if (this == &rhs) 
     return *this; 

    delete[] mArray; 

    mSize = rhs.mSize; 

    mArray = new int[mSize]; 

    for (int i = 0; i < mSize; i++) 
    { 
     mArray[i] = rhs.mArray[i]; 
    } 

    return *this; 
} 

int& IntArray::operator[](int i) 
{ 
    return mArray[i]; 
} 

Благодарим за любую помощь. EDIT2: Да, я знаю, что вектор - это то же самое, что и я. Не в этом дело. Я просто пытаюсь лучше понять указатели и динамическую память внутри классов, и это упражнение из книги, которая просто дала мне код файла заголовка и попросила меня реализовать его.

+0

Какое сообщение об ошибке? – ecatmur

+5

'mArray = new int (newSize)' может быть неправильным. – Martze

+1

Почему вы выделяете новый массив, чтобы сделать идеальную копию, а затем выбросить оригинал? Почему бы просто не использовать оригинал для какой-либо цели, которую вы хотели получить? (Почему не просто 'temp = mArray; mArray = new int (newSize), ...' –

ответ

2

Функция resize не установлена ​​mSize, поэтому более поздние операции могут привести к проблемам.

Вот более эффективному осуществлению

void IntArray::resize(int newSize) 
{ 

    if (newSize == 0) 
    { 
     mSize = 0; 
     delete[] mArray; 
     mArray = 0; 
    } 
    else 
    { 
     int *newArray = new int [newSize]: 
     for (int i = 0; (i < newSize) && (i < mSize); ++i) 
      newArray[i] = mArray [i]; 
     delete[] mArray; 
     mArray = newArray; 
     mSize = newSize; 
    } 
} 
+0

Я действительно нашел это и реализовал его пару минут назад. Затем пришел сюда, и вы отредактировали свой ответ. Это то, что я искал :). В основном я не устанавливал msize, как вы говорили, но мне также нужно было установить адресное расположение mArray в newArray вместо того, что я делал, и удалить newArray. – Cush

2

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

void IntArray::resize(int newSize) 
{ 
    int* temp = new int[newSize]; //Create temp dynamic array to store the values 
    memcpy(temp, mArray, sizeof(int)*(mSize > newSize ? newSize : mSize)); 
    delete[] mArray; 
    mSize = newSize; 
    mArray = temp; 
} 

Но вы можете иметь утечку памяти, если будут исключения. Использование вектора лучше.

+0

Это определенно работает. Только проблема, с которой я сталкиваюсь, заключается в том, что я понятия не имею, как это работает xD. Книга никогда не переходила на функцию memcpy раньше. Мне нужно будет это посмотреть, но я уверен, что как только я это просмотрю, я буду очень смущен указателем, который у вас есть для функции sizeof. Функция sizeof из того, что я помню, дает мне количество байтов, в вашем случае целое число 4, тип имеет. Или это на самом деле разыменовывает то, что находится в скобках справа, а не указатель на sizeof? – Cush

+0

@Cush, вы знаете, что новый Entity [] будет выделять один блок памяти. Будет newSize из ints, поэтому в байтах будут sizeof (int) * newSize байты. Итак, вы выделяете необходимую вам память. Затем вы копируете выделенные байты памяти из старой памяти. А затем сохраните выделенную память в своем классе. Посмотрите на функцию 'memcpy', на'? : 'оператор. Все будет ясно для вас. – Arkady

+0

Вместо memcpy вы можете использовать std :: copy (...), возможно, это будет чище. – Arkady

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