Runtime error about undefined behavior

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



tw.cpp:53:19: runtime error: member access within address 0x7fe7f52ff800 which does not point to an object of type 'CachedObj'
0x7fe7f52ff800: note: object has invalid vptr
 00 00 00 00  be be be be be be be be  be be be be be be be be  be be be be be be be be  be be be be
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr
tw.cpp:41:39: runtime error: member access within address 0x7fe7f53ff7c0 which does not point to an object of type 'CachedObj'
0x7fe7f53ff7c0: note: object has invalid vptr
 00 00 00 00  00 00 00 00 00 00 00 00  a0 f7 3f f5 e7 7f 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr
I am referring to a derived class. Access to the "next" member of the base class.Is this a runtime error?
---------------------------------------------
Compile command:
g++ -std=c++98 -O0 --ansi -fno-elide-constructors -Wall -fsanitize=address -fsanitize=undefined -g $name ; ASAN_OPTIONS=detect_leaks=1
./a.out

#include <iostream>
#include <cstddef>
#include <bits/allocator.h>
#include <stdexcept>
using std::cout;
using std::endl;

template <class T> class CachedObj {
    public:
	void *operator new(std::size_t);
	void operator delete(void *, std::size_t);
	virtual ~CachedObj()
	{
	}

    protected:
	T *next;

    private:
	static void add_to_freelist(T *);
	static std::allocator<T> alloc_mem;
	static T *freeStore;
	static const std::size_t chunk;
};

template <class T> std::allocator<T> CachedObj<T>::alloc_mem;
template <typename F> F *CachedObj<F>::freeStore = 0;
template <class T> const std::size_t CachedObj<T>::chunk = 32767;
template <class T> void *CachedObj<T>::operator new(size_t sz)
{
	if (sz != sizeof(T))
		throw std::runtime_error(
			"CachedObj:wrong size object in operator new");
	if (!freeStore) {
		T *array = alloc_mem.allocate(chunk);
		for (size_t i = 0; i != chunk; ++i)
			add_to_freelist(&array[i]);
	}
	T *p = freeStore;
	freeStore = freeStore->CachedObj<T>::next;
	return p;
}

template <class T> void CachedObj<T>::operator delete(void *p, size_t)
{
	if (p != 0)
		add_to_freelist(static_cast<T *>(p));
}
template <class T> void CachedObj<T>::add_to_freelist(T *p)
{
	p->CachedObj<T>::next = freeStore;
	freeStore = p;
}

template <class Type> class Queue;
template <class T> std::ostream &operator<<(std::ostream &, const Queue<T> &);

template <class Type> class QueueItem : public CachedObj<QueueItem<Type> > {
	friend class Queue<Type>;
	friend std::ostream &operator<< <Type>(std::ostream &,
					       const Queue<Type> &);
	QueueItem(const Type &t)
		: item(t)
		, next(0)
	{
	}
	Type item;
	QueueItem *next;
};

template <class Type> class Queue {
	friend std::ostream &operator<< <Type>(std::ostream &,
					       const Queue<Type> &);

    public:
	Queue()
		: head(0)
		, tail(0)
	{
	}

    public:
	template <class It>
	Queue(It beg, It end)
		: head(0)
		, tail(0)
	{
		copy_elems(beg, end);
	}

	Queue(const Queue &Q)
		: head(0)
		, tail(0)
	{
		copy_elems(Q);
	}
	Queue &operator=(const Queue &);
	~Queue()
	{
		destroy();
	}

	template <class Iter> void assign(Iter, Iter);

	Type &front()
	{
		return head->item;
	}
	const Type &front() const
	{
		return head->item;
	}

	void push(const Type &);
	void pop();

	bool empty() const
	{
		return head == 0;
	}

    private:
	QueueItem<Type> *head;
	QueueItem<Type> *tail;
	void destroy();
	void copy_elems(const Queue &);

    private:
	template <class Iter> void copy_elems(Iter, Iter);
};

template <class Type> void Queue<Type>::copy_elems(const Queue &orig)
{
	for (QueueItem<Type> *pt = orig.head; pt; pt = pt->next)
		push(pt->item);
}

template <class Type> Queue<Type> &Queue<Type>::operator=(const Queue &rhs)
{
	if (this != &rhs) {
		destroy();
		copy_elems(rhs);
	}
	return *this;
}

template <class Type> void Queue<Type>::destroy()
{
	while (!empty())
		pop();
}

template <class Type> void Queue<Type>::push(const Type &val)
{
	QueueItem<Type> *pt = new QueueItem<Type>(val);

	if (empty())
		head = tail = pt;
	else {
		tail->next = pt;
		tail = pt;
	}
}

template <class Type> void Queue<Type>::pop()
{
	QueueItem<Type> *p = head;
	head = head->next;
	delete p;
}

template <class Type>
std::ostream &operator<<(std::ostream &os, const Queue<Type> &q)
{
	os << "< ";
	QueueItem<Type> *p;
	for (p = q.head; p; p = p->next)
		os << p->item << " ";
	os << ">";
	return os;
}

template <class T>
template <class Iter>
void Queue<T>::assign(Iter beg, Iter end)
{
	destroy();

	copy_elems(beg, end);
}

template <class Type>
template <class It>
void Queue<Type>::copy_elems(It beg, It end)
{
	while (beg != end) {
		push(*beg);
		++beg;
	}
}

int main()
{
	Queue<int> queue1;

	for (int ix = 0; ix != 32767; ++ix)
		queue1.push(ix);

	for (int ix = 0; ix != 32767; ++ix) {
		int i = queue1.front();
		if (i != ix)
			cout << "Something's wrong! i = " << i << " ix = " << ix
			     << endl;
		queue1.pop(); // and remove it
	}

	if (!queue1.empty())
		cout << "Queue is not empty but should be!" << endl;
	else
		cout << "OK, queue empty again" << endl;

	for (int ix = 0; ix != 32767; ++ix)
		queue1.push(ix);

	Queue<int> queue2(queue1); // use copy constructor

	for (int ix = 0; ix != 32767; ++ix) {
		int i = queue2.front(); // check next item
		if (i != ix)
			cout << "Something's wrong! i = " << i << " ix = " << ix
			     << endl;
		queue2.pop(); // and remove it
	}

	if (!queue2.empty())
		cout << "queue2 is not empty but should be!" << endl;
	else
		cout << "OK, queue2 empty again" << endl;

	queue2 = queue1; // use asssignment operator
	for (int ix = 0; ix != 32767; ++ix) {
		int i = queue2.front();
		if (i != ix)
			cout << "Something's wrong! i = " << i << " ix = " << ix
			     << endl;
		queue2.pop();
	}

	if (!queue2.empty())
		cout << "queue2 is not empty but should be!" << endl;
	else
		cout << "OK, queue2 empty again" << endl;
	return 0;
}

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux