LINUX.ORG.RU

C++ потеря адреса (MSVC++)


0

0

Добрый вечер форумчане.

Появилась проблема. Такого я в своей жизни еще не встречал. Помогите пожалуйста решить, возможно это я глубоко ошибаюсь.

Код:

template<typename T>
void ArrayList<T>::realloc(int new_size)
{
// Allocating new array
T *nbuf = new T[new_size];
T *nbuf_end = nbuf + new_size;
// copying old values to new buffer
T* n_curr = nbuf;
if (itemBuf) {
T *o_curr;
for (o_curr = itemBuf; n_curr < nbuf_end && o_curr < lastItem; ++n_curr, ++o_curr)
*n_curr = *o_curr;
delete[] itemBuf;
}
itemBuf = nbuf;
itemBuf_end = nbuf_end;
lastItem = n_curr;
}

Что происходит:
При T = bool
Код
T *nbuf = new T[new_size]; // Тут все нормально
T *nbuf_end = nbuf + new_size; // Тут nbuf теряет свое значение, nbuf_end в свою очередь приобретает NULL.

При T = int
Такого не замечено. Но замеяаются другие деффекты в других методах. Если эта проблема решится, деффекты, думаю исправлю сам.

какая студи? на восьмерке не репродуцировалось.

И привиди минимальный кусок (компилируемого) кода,
на котором у тебя репродуцируется проблема

aton
()
Ответ на: комментарий от aton

template <typename T>
class ArrayList
{
	public:
		ArrayList()
        	: itemBuf(0)
            , itemBuf_end(0)
            , lastItem(0)
        {
        }
        ArrayList(const ArrayList<T> &l);
		~ArrayList()
        {
			if (itemBuf)
				delete[] itemBuf;
		}
		void add(const T &item);
		void add(const T &item, int index);
		void remove(int index);
		T &get(int index) const;
		int length() const;
		
		void clear();

		T& operator[] (int index) {
			return get(index);
		}

		ArrayList<T> &operator += (T &item) {
			add(item);
			return *this;
		}
	private:
		// Size, allocated for items (Count of items, can be inserted into buf without realloc)
		int getSize() const;
		int getLeftSize() const;

		void tryResizeBuf(int new_size);
		void realloc(int new_size);
	private:
		// Pointer to the begining of the bufer
		T *itemBuf;
		// Pointer to the end of the buffer
		T *itemBuf_end;
		// Pointer to the current intem
		T *lastItem;
};


const int BUF_GROW_INCREMENT_SIZE = 1;

template<typename T>
int ArrayList<T>::getSize() const
{
	return (int)(itemBuf_end - itemBuf);
}

template<typename T>
int ArrayList<T>::getLeftSize() const
{
	return getSize() - length();
}

template<typename T>
int ArrayList<T>::length() const
{
	return (int)(lastItem - itemBuf);
}

template<typename T>
void ArrayList<T>::realloc(int new_size)
{
	// Allocating new array
	T *new_buf = new T[new_size];
	T *new_buf_end = new_buf + new_size;
	// copying old values to new buffer
	T* n_curr = new_buf;
	if (itemBuf) {
		T *o_curr;
		for (o_curr = itemBuf; n_curr < new_buf_end && o_curr < lastItem; ++n_curr, ++o_curr)
			*n_curr = *o_curr;
		delete[] itemBuf;
	}
	itemBuf = new_buf;
	itemBuf_end = new_buf_end;
	lastItem = n_curr;
}

template<typename T>
void ArrayList<T>::tryResizeBuf(int new_size)
{
	if (getSize() <= new_size)
		realloc(getSize()+BUF_GROW_INCREMENT_SIZE);
	else if (getSize() > new_size+BUF_GROW_INCREMENT_SIZE)
		realloc(getSize()-BUF_GROW_INCREMENT_SIZE);
}

template<typename T>
void ArrayList<T>::add(const T &item)
{
	tryResizeBuf(length()+1);
	*(lastItem++) = item;
}

template<typename T>
void ArrayList<T>::add(const T &item, int index)
{
	if (index == length())
		add(item);
	else {
		tryResizeBuf(length()+1);
		for (int i=length(); i > index; --i)
			itemBuf[i] = itemBuf[i-1];
		itemBuf[index] = item;
		lastItem++;
	}
}

template<typename T>
void ArrayList<T>::remove(int index)
{
	T *curr = itemBuf+index;
	T *next = curr+1;
	for (; next < lastItem; ++next, ++curr)
		*curr = *next;
	lastItem = lastItem-1;
	tryResizeBuf(length());
}

template<typename T>
T &ArrayList<T>::get(int index) const
{
	return itemBuf[index];
}

template<typename T>
void ArrayList<T>::clear()
{
	delete[] itemBuf;
	itemBuf = itemBuf_end = lastItem = 0;
}


template<typename T>
ArrayList<T>::ArrayList(const ArrayList<T> &l)
{
	T *nbuf = new T[l.getSize()];
    itemBuf = nbuf;
	lastItem = itemBuf + l.length();
    itemBuf_end = itemBuf + l.getSize();
    for (int i=0; i < length(); ++i)
    	itemBuf[i] = l.itemBuf[i];
}

#endif


ArrayList<bool> l;
l.add(1);
l.add(2, 2);
l.remove(1);
l.get(0);
// Heap Block Damaged

mutable
() автор топика
Ответ на: комментарий от mutable

Теперь я этот класс переписал, что бы нагляднее было, но продлемы не лишился:

template <typename T>
class ArrayList
{
	public:
		ArrayList()
        	: itemBuf(0)
			, size(0)
            , last_index(0)
        {
        }
        ArrayList(const ArrayList<T> &l);
		~ArrayList()
        {
			if (itemBuf)
				delete[] itemBuf;
		}
		void add(const T &item);
		void add(const T &item, int index);
		void remove(int index);
		T &get(int index) const;
		int length() const;
		
		void clear();

		T& operator[] (int index) {
			return get(index);
		}

		ArrayList<T> &operator += (T &item) {
			add(item);
			return *this;
		}
	private:
		void tryResizeBuf(int new_size);
		void _zzz_realloc(int new_size);
	private:
		// Pointer to the begining of the bufer
		T *itemBuf;
		// Pointer to the end of the buffer
		int size;
		// Pointer to the current intem
		int last_index;
};


const int BUF_GROW_INCREMENT_SIZE = 1;

template<typename T>
int ArrayList<T>::length() const
{
	return last_index;
}

template<typename T>
void ArrayList<T>::_zzz_realloc(int new_size)
{
	// Allocating new array
	T *nbuf = new T[new_size];
	// copying old values to new buffer
	if (itemBuf) {
		for (int i=0; i < last_index; ++i)
			nbuf[i] = itemBuf[i];
		delete[] itemBuf;
	}
	itemBuf = nbuf;
	size = new_size;
}

template<typename T>
void ArrayList<T>::tryResizeBuf(int new_size)
{
	if (size <= new_size)
		_zzz_realloc(size+BUF_GROW_INCREMENT_SIZE);
	else if (size > new_size+BUF_GROW_INCREMENT_SIZE)
		_zzz_realloc(size-BUF_GROW_INCREMENT_SIZE);
}

template<typename T>
void ArrayList<T>::add(const T &item)
{
	tryResizeBuf(length()+1);
	itemBuf[last_index++] = item;
}

template<typename T>
void ArrayList<T>::add(const T &item, int index)
{
	if (index == length())
		add(item);
	else {
		tryResizeBuf(length()+1);
		for (int i=length(); i > index; --i)
			itemBuf[i] = itemBuf[i-1];
		itemBuf[index] = item;
		last_index++;
	}
}

template<typename T>
void ArrayList<T>::remove(int index)
{
	for (int i=index; i < last_index-1; ++i)
		itemBuf[i] = itemBuf[i+1];
	tryResizeBuf(--last_index);
}

template<typename T>
T &ArrayList<T>::get(int index) const
{
	return itemBuf[index];
}

template<typename T>
void ArrayList<T>::clear()
{
	delete[] itemBuf;
	itemBuf = 0;
	last_index = size = 0;
}


template<typename T>
ArrayList<T>::ArrayList(const ArrayList<T> &l)
{
	T *nbuf = new T[l.size];
	itemBuf = nbuf;
	last_index = l.last_index;
	size = l.size;
	for (int i=0; i < last_index; ++i)
		itemBuf[i] = l.itemBuf[i];
}

mutable
() автор топика
Ответ на: комментарий от mutable

Спасибо. Нашел. (Сам ступил)

template<typename T>
void ArrayList<T>::add(const T &item, int index)
{
	if (index == last_index)
		add(item);
	else {
		tryResizeBuf(index); // !!!!! было tryResizeBuf(last_index+1);
		for (int i=length(); i > index; --i)
			itemBuf[i] = itemBuf[i-1];
		itemBuf[index] = item;
		last_index++;
	}
#	ifdef _zzz_DEBUG
	test_vector.insert(test_vector.begin()+=index, item);
	for (int i=0; i < last_index; ++i)
		assert(test_vector[i] == (*this)[i]);
#	endif
}

mutable
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.