Member 12780386 Ответов: 2

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


#include <iostream>
#include <vector>
#include <iomanip>
#include <array>
#include <cassert>
using namespace std;

class container {
	friend ostream& operator<<(ostream& out, container &);
	// Postcondition: displays # of values stored in the container, storage capacity of the contianer, and stored values in the container 
	//                in the following format: Array size = 3, capacity = 4, contents = 11, 22, 33 (see below sample program output

public:
	container();
	// Postcondition: set dynamic storage capacity to 1 and count to -1 where (count + 1) represents the actual values stored 
	//                 in the container. Notice that data member count is used as the subscript to access elements (actual values) stored 
	//                 in the dynamic array; thus (count + 1) represents the total # of values that are currently stored in the array

	container(int n);
	// Postcondition: set dynamic storage (data array) capacity to n and count to -1

	container(container &c);
	// Programmer-supplied copy constructor is necessary to avoid memory leak and other side effect
	// Postcondition: a new container class object is created which is the same as the one passed to the function

	~container();
	// Programmer-supplied destructor is necessary to avoid memory leak
	// Postcondition: all dynamic memory locations have been returned back to the heap whenever a container object goes out of scope

	container& operator=(container &rhs);
	// Programmer-supplied overloaded assignment is necessary to avoid memory leak and other side effect
	// Postconditoin: the container object rhs is assigned to the calling object

	void insert(int value);
	// Postcondition: if the container is not full, the value passed to the function is stored in  
	//			the first available element of the dynamic array. Otherwise the function calls the private 
	//         	       "allocate" member function requesting a new set of dynamic memory with twice the previous storage capacity 
	//			the insert function then increments count by 1 and insert the value into the new and larger array.

	void remove();
	//  Precondition: the data array must not be empty; i.e., count must be greater than or equal to 0.
	// Postcondition: if the container is not empty, then remove the most recently stored value ifrom the container and 
	//			decrement count by 1; otherwise, display the message "The container is empty; no action is taken!"

	int operator[](int sub);
	//  Precondition: value passed to the function must be a positive integer including 0
	// Postcondition: the value of stored in data[sub] is returned; if sub is out of range, display a message and terminate the program .

	bool isFull();
	// Postcondition: return true if the container is full; return false otherwise 

	bool isEmpty();
	// Postcondition: return true if the container is empty; return false otherwise

	int Capacity();
	// Notice uppercase 'C' to avoid conflict with data member named "capacity"
	// Postcondition: returns the current storage capacity of the container

	int size();
	// Postcondition: returns the # of elements (# of objects) currently stored in the container

	void resize(int n);
	// Postcondition: container (i.e., the dynamic array) is resized to n; contents of existing container have been copied to the new array; 
	// 			      old array is deleted to avoid memory leak.

private:
	void allocate();
	// Postcondition: 1) the capacity of the container has been doubled, 2) existing values in the existing array have been copied to 
	//				   the new and larger dynamic array, 3) memory of the old array has been deleted (returned to "heap").

	int *data;
	int capacity;		// indicates the storage capcity of the container, i.e., the size of the dynamic array		
	int count;		// used as a subscript to index into the array; size = count + 1
};
int main()
{
	container c1;
	bool status = c1.isEmpty();
	if (status = true)
		cout << "contents of container is empty" << endl;
	else
		cout << "contianer is not empty" << endl;
	//c1.(5);
	//c1.insert(2);
	for (int i = 1; i <=9; i++)
		c1.insert(11*i);
	cout <<c1 << endl;
	/*cout << "Container c2 contains:" << endl;
	container c2(c1);
	cout<<c2<<endl;
	container c3 =c2;
	cout << "Container c3 contains:" << endl;
	cout << c3 << endl;
	c3.resize(4);
	cout << c3 << endl;
	c3.resize(7);
	cout << c3 << endl;
	cout << "Address of c1 = " << &c1 << endl;
	cout << "Address of c2 = " << &c2 << endl;
	cout << "Address of c3 = " << &c3 << endl;*/
	system("pause");
	return 0;
}
container::container()
{
	capacity = 1;
	data = new int[capacity];
	count = -1;
	assert(data !=NULL);
}
container::container(int n)
{
	count = -1;
	capacity = n;
	data = new int[capacity];
	assert(data !=NULL);
}
container::container(container &c)
{
	capacity = c.capacity;
	count=c.count;
	data = new int[capacity];
	assert(data !=NULL);
	for (int i = 0; i < capacity; i++)
		data[i] = c.data[i];
}
container::~container()
{
	delete[]data;
}
container& container:: operator=(container &rhs)

{
	if (this != &rhs)
	{
		delete data;
		data = rhs.data;
		rhs.data = nullptr;
	}
	return (*this);

}

void container::insert(int x)
{
	//cout << count;
	if (isFull())
		++count;
	(*this).allocate();
	(*this).data[count] = x;
}

bool container::isFull()
{
	bool status;

	if (count == capacity - 1)
		status = true;
	else
		status = false;
	return status;
}
void container::allocate()
{
	int *temp;
	temp = new int[2 * capacity];
	for (int i = 0; i < count; i++)
		temp[i] = data[i];
	capacity = 2 * capacity;
	for (int i =0; i<count; i++)
	data = temp;
	delete[]data;
}
int container::operator[] (int sub)
{
	int num;
	if (sub<0)
	{

		cout << "sub is out of range";
		exit(1);
	}
	num = data[sub];
	return num;
}
bool container::isEmpty()
{
	if (count == -1)
		return true;
	else
		return false;
}
ostream& operator<<(ostream& out, container & obj)
{

	out << "The 'container' contains the following " << obj.count + 1 << " value(s):\n";
	if (obj.count == -1)
		out << "*** data array is empty!" << endl;
	else
	{
		for (int i = 0; i <= obj.count; i++)
			out << obj.data[i] << '\t';
		out << endl;
	}
	return out;
}
int container::Capacity()
{
	return capacity;
}
void container::resize(int n)
{
	int *temp;
	temp = new int[n];
	assert(temp != NULL);
	if (count + 1 < n)
		for (int i = 0; i <= count; i++)
			temp[i] = data[i];
	else
	{
		for (int i = 0; i < n; i++)
			temp[i] = data[i];
		count = n - 1;
	}
	capacity = n;
	delete[] data;
	data = temp;

}


Что я уже пробовал:

я просто пытаюсь заставить его работать

NotPolitcallyCorrect

Скорее всего, кто-то где-то столкнулся именно с вашей проблемой. г-н Google может сказать вам, что это за ошибка и что вы можете сделать, чтобы отладить свой код. Умение отлаживать код-это ценный навык, который вы должны развивать.

2 Ответов

Рейтинг:
2

Patrice T

Попробуйте сказать нам, где происходит ошибка.

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

Отладчик позволяет вам следить за выполнением строка за строкой, проверять переменные, и вы увидите, что есть точка, в которой он перестает делать то, что вы ожидаете.
Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
Когда код не делает того, что ожидается, вы близки к ошибке.


Рейтинг:
1

Jochen Arndt

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

[РЕДАКТИРОВАТЬ]
Ошибка кучи возникает при доступе к элементам объектов, расположенных в куче (выделенных с помощью new или одна из функций распределения C, таких как malloc) вне пределов досягаемости. С массивами это происходит при использовании индекса, выходящего за пределы размера массива (index >= size или negative). Это происходит также, когда указатель памяти недействителен (NULL, неопределенное или случайное значение, или память была удалена между тем).
[/РЕДАКТИРОВАТЬ]

container& container:: operator=(container &rhs)
{
    if (this != &rhs)
    {
        delete data;
        data = rhs.data;
        rhs.data = nullptr;
        // What happens when rhs.capacity or rhs.count are not identical 
        //  to this->capacity and this->count ?
        // Especially when the rhs values are smaller and 
        //  acessing an element beyond the data size later?
        // What happens when accessing elements of rhs afterwards?
        // Tip: The count and capacity members of rhs still indicate that there are data
    }
    return (*this);
}

void container::allocate()
{
    int *temp;
    temp = new int[2 * capacity];
    for (int i = 0; i < count; i++)
        temp[i] = data[i];
    capacity = 2 * capacity;
    // ??? 
    // Not an error but useless
    // I have indented the follwing line to show what happens
    for (int i =0; i<count; i++)
        data = temp;
    // You are deleting the newly created storage here!
    // This must be moved up before the
    //  data = temp 
    // statement to delete the old array.
    delete[]data;
}

int container::operator[] (int sub)
{
    int num;
    if (sub<0)
    {
        cout << "sub is out of range";
        // Why do you use exit here?
        // Throwing an exception would be the common C++ method
        exit(1);
    }
    // What happens when sub is greater than count?
    num = data[sub];
    return num;
}


[РЕДАКТИРОВАТЬ]
Решение:
У вас есть три переменные-члена, которые указывают на состояние вашего контейнера:
data, capacity, и count
При выполнении операций необходимо убедиться, что все они обновляются, если на них влияет операция.
[/РЕДАКТИРОВАТЬ]