Understanding Delete [] c++ - c++

Before all let me say that i have already search for an answer, and i can't find any that explains to me why i'm having problems.
Im a student and im now learning C++
So before tell me to not use C++ in this way, let me say to you that it is for learning purposes and understanding of some comcepts.
Program crashes at very last statement. delete[] tempVector;
I cant understand why it happens since delete[] vector; works just fine.
The error: play with arr.exe has triggered a breakpoint
Please help me to understand what im doing wrong.
Thank you a lot.
class BetterArray
{
private:
int* vector;
int count;
public:
BetterArray(int value);
BetterArray(int* vec, int size);
~BetterArray();
void add(int value);
int* getArray();
};
BetterArray::BetterArray(int value)
{
count = 1;
vector = new int[1];
vector[0] = value;
}
void BetterArray::add(int value){
int* tempVector = new int[count + 1];
for (int i = 0; i < count; i++)
tempVector[i] = vector[i];
tempVector[count] = value;
count++;
delete[] vector;
vector = tempVector;
delete[] tempVector; // programa crahses here.
}

Crash on delete is often a result of a heap corruption. When you assign the tempVector pointer to vector both pointer point to the same memory location. So deleting tempVector also deletes vector. vector now points to unassigned memory.
Now assuming you write to vector, you are writing to unassigned memory which will corrupt the heap. What happens after this is undefined behaviour but if the heap manager detects the corruption, it will often just crash.

Related

How do I allocate memory with "new" instead of malloc?

As a homework I have to write a program that operates around structures. As a first task i have to write a function that allocates memory for an array of N pointers that point to new structures(user decides about the value of N) and returns the adress of an array. The first problem that i have is understanding the form of malloc. I asked my professor what would be the equivalent by using "new" because it is more transparent for me but he answered that I should stick to malloc so i avoid making any mistakes. The following function looks like this:
struct Structure
{
int a;
char b;
float c;
};
Structure** allocating(int N)
{
struct Structure** tab = (struct Structure**) malloc(amount * sizeof(struct Structure*));
for (int i = 0; i < N; i++)
{
tab[i] = (struct Structure*) malloc(sizeof(struct Structure));
}
return tab;
}
I have tried understanding this form of allocating memory but so far i understand this as if i was allocating memory for a pointer pointing to the array of pointers(double **) which is not what was stated in a task. To sum up, i don't understand the way the allocating is written and how could it be written by using new.
Your C code allocates an array of pointers to Structure. I have no idea why it is done this way instead of simply allocating an array of Structure, you have to ask the author of the task for that.
Direct equivalent using new would look like this :
Structure** allocating(int N)
{
struct Structure** tab = new Structure*[N];
for (int i = 0; i < N; i++)
{
tab[i] = new Structure;
}
return tab;
}
Deallocating can be a bit tricky:
void deallocating(Structure** tab, int N)
{
for (int i = 0; i < N; i++)
{
delete tab[i]; //delete objects
}
delete[] tab; //delete array itself, notice the [] after delete!
}
If you can move to array of objects instead of array of pointers, the code gets much simpler:
Structure* allocating(int N)
{
return new Structure[N];
}
Later you also deallocate it with delete[]
As noticed in comments, in C++ we prefer to not use memory management directly (especially in modern C++ keyword new is considered to be a bad smell). std::vector can handle all your array-on-the-heap needs perfectly well, it will never leak memory and can resize itself easily.

Destruct array of vectors in C++

I have questions about the destructing process of STL vector as well as array of vectors. The only thing I learned from my teacher is the number of delete is equal to the number of new. I have 3 questions for the array of vector in different contexts. To be convenient, all of the array has 5 vectors. Each vector has 1 element.
1. Array of vectors appears in main.cpp
int main(){
int size = 5;
vector<int> *array_vec = new vector<int>[size];
for(int i=0; i<size; i++){
array_vec[i].push_back{i};
}
delete [] array_vec;
return 0;
}
Question 1: At the end of the main() function, I manually delete the array by delete [] array_vec, but I don't manually free each vectors array_vec[i]. Was the array_vec[i]'s memory released automatically? If yes, when? (before OR after my delete [] array_vec?) The reason why I ask this question is for 2D dynamic array, we must free the inner array before the outer array, so I wonder whether it is the case for the array of vector.
2. Array of vectors appears in a class's method as a temporary variable
Class myClass{
public:
void myMethod(){
int size = 5;
vector<int> *array_vec = new vector<int>[size];
for(int i=0; i<size; i++){
array_vec[i].push_back(i);
}
delete [] array_vec;
}
}
int main(){
myClass myclass;
myclass.myMethod();
/** some other process in the program **/
return 0;
}
Question 2: Was the array_vec[i] released before the myclass.myMethod() returned? OR array_vec[i] will only be released at the end of the entire program?
3. Array of vectors appears in a class as a class property
Class myClass{
public:
vector<int> *array_vec;
public:
~myClass(){
if(array_vec)
delete [] array_vec;
}
void Init(){
int size = 5;
array_vec = new vector<int>[size];
for(int i=0; i<size; i++){
array_vec[i].push_back(i);
}
}
void Use(){
std::cout<<array_vec[0][0]<<std::endl;
}
}
int main(){
myClass myclass;
myclass.Init();
myclass.Use();
/** some other process in the program **/
return 0;
}
Question 3: Is my destructor OK? In my ~myClass() method, I just free the array of vectors array_vec, but I do not know whether those vectors themselves will be free automatically or not? If yes, that will be good. If no, when will they be released? How can I manually free those vectors?
This problem has confused me for a long time. The memory issue is very important for my c++ program, because I need to use array of vectors in a big loop. If the memory is not released correctly, the memory usage will be larger and larger while the program is running. In that case, my program will crash. Really appreciate your help.
All of your examples are fine. std::vector takes care of cleaning up the memory it owns. That's why you use it instead of raw pointers.
In all of the cases you posted, you should use a std::vector<std::vector<int>> instead though. That will free you from having to deal with memory management at all, and help avoid easy mistakes, like the rule of three violation in your third example.

Unreadable memory when I create pointer array in c++

I'm new to pointers and dynamic memory. The program is supposed to be an array-based stack.
I need help with an error that occurs when I try to allocate memory to the pointer variable _pArr in the .h-file. When I try to create a new array with new double[] I get an 'unreadable memory' error message when I debug the code.
In the code down below I have created a new array in the .cpp-file and then copy it to the _pArr pointer, but I still get the same error.
class CStack{
public:
Stack(void);
~Stack(void);
.
.
.
private:
int _capacity=NULL;
int _size=0;
double* _pArr;
}
CStack::CStack(void)
{
if (_capacity == 0){
_capacity = 10;
}
else{
_capacity = _capacity * 2;
}
double* arr;
arr = new double [_capacity]
_pArr=arr;
delete[] arr;
}
Why does this error occur and how can I fix it?
Here's what your code is doing in the constructor:
// Allocate memory for an array and set arr to point to that array.
double* arr;
arr = new double [_capacity]
// Set _pArr to point to the same array.
_pArr=arr;
// Delete the array that arr and _pArr point to. If you
// deference _pArr after this, bad things will happen.
delete[] arr;
So you shouldn't be deleting the array immediately after you allocated it. (There's also a missing semicolon there.) Getting rid of that will likely fix your problem, but then you then need to delete the array in the class's destructor. And if you must use new[]/delete[], it would be far easier to do it in a single step, rather than creating a useless temporary variable:
CStack::CStack(void)
{
if (_capacity == 0){
_capacity = 10;
}
else{
_capacity = _capacity * 2;
}
_pArr = new double [_capacity];
}
CStack::~CStack(void)
{
delete[] _pArr;
}
Unrelated to your question, but that code that doubles _capacity doesn't do anything useful, as capacity will always be zero when the constructor is called. If you intended for this to expand an existing CStack, then you will need to put it in a method, and will need to worry about creating a new array for the stack, copying the contents of the old one into the new, and then deleting the old one.

Infinite size Stack implementation using pointer to an array

I have been trying to make a infinite size stack using pointer to any int:
//in class:
int* stack;
//In constructor:
stack = new int();
//In deconstructor:
delete stack;
//In Push:
stack(++top) = element;
Is this declaration correct? Can I use this to make an infinite size stack? I run into error when I try to put elements into the stack using such pointer declaration.
It seems you are writing codes in C++? If no, please just ignore my post(face palm).
Firstly, the memory that could be assigned to a program is limited, i.e. no infinite size stack. In C++, there is BSS, Stack and Heap memory. In your case, you have used new operator to assign memory. This in fact effectively means you would like to get a piece of memory in the heap to store your value. Though the size of heap could be dynamically extended, its memory size is still not infinite.
Moreover, it seems what you would like to do in the constructor is to build up an int array with unlimited size. In fact, to declare an array, you may write new int[arraySize] to declare an int array of size, arraySize, in the heap. However, what you have written here is allocating a single int in the heap since the brackets you used are not square, but round. Unfortunately, to create an array, you need to declare its size first (for more details, you may search for stack array and dynamic array). So as to get rid of the size problem, you may use other data structures like std::vector and so forth for simple.
int* stack;
stack = new int();
These 2 statements are to have a pointer pointing to a single int stored in heap memory. Therefore, currently, the stack you make seems to be only able to store an int only.
As for the push function, top is the index of the top int in the stack?
One more thing, in case, what you want to make is creating a pointer to point an int array, and use the array as a stack. Then, you may think about the way to add memory, and have the deconstructor revised to be like this:
delete[] stack;
If you find difficulty in understanding my above paragraphs and have interest in learning more, perhaps you may firstly learn about stack & heap, then, the array declaration as well as its relationship with the memory allocation, followed by the knowledge about pointers.
I am a newbie. Hopefully, I haven't made any mistake in my answer.
First of all new int () creates only a single int not an array of integers therefore you can't do something like stack(++top) = element;.
If you want to create a dynamic array you should use int* stack = new int[size] and delete it with delete [] stack. As you can see the array has a limited size of size but you can resize it when it becomes full. There is no built-in way to resize the array but you can create a new dynamic array with bigger size and copy the old array into it and then remove the old array. But again the stack won't have infinite size since your memory is limited. If the allocation fails an exception will be thrown.
Below is a simple implementation of stack based on a dynamic array.
#include <stdexcept>
using namespace std;
class Stack{
public:
Stack (int _size = 20){
size = _size;
topIndex = 0;
stack = new int [size];
}
~Stack (){
delete [] stack;
}
void resize(){
int new_size = size*2;
int * new_stack;
// try{
new_stack = new int[new_size];
// } catch (std::bad_alloc&) {
// unsuccessful allocation
// }
for ( int i=0; i<size; ++i ){
new_stack[i] = stack[i];
}
delete [] stack;
stack = new_stack;
size = new_size;
}
void push(int element){
if (topIndex + 1 == size){
resize();
}
stack[topIndex++] = element;
}
int top(){
if ( topIndex <= 0 ){
throw std::out_of_range("stack is empty");
} else {
return stack[topIndex-1];
}
}
void pop(){
if ( topIndex <= 0 ){
throw std::out_of_range("stack is empty");
} else {
--topIndex;
}
}
private:
int * stack;
int size;
int topIndex;
};
int main(){
Stack stk;
for ( int i=0;i<50;++i ){
stk.push(i);
cout << stk.top() << endl;
}
for ( int i=0;i<50;++i ){
stk.pop();
cout << stk.top() << endl;
}
}
Note that this is all just for practice and the above implementation is error prone. You should almost always use built-in data structures in practical situations.

C++ array of pointer memory leaks

In my class I have a dynamically allocated array of pointers. My declaration:
array = new Elem* [size];
for (int i = 0; i < size; i++) {
array[i] = NULL;
}
So there is an array of pointers, where each pointer points to a simple Elem struct.
The main question is, how should I properly deallocate the array. If I use only:
for (int i = 0; i < size; i++) {
delete array[i];
}
Valgrind reports 1 not-freed block, which is traced to the line where 'array = new Elem* [size];' states.
On the other hand if I add to the previous code:
delete array;
Which I thought is correct, valgrind reports 0 not-freed blocks, which is perfect, BUT it reports
Mismatched free() / delete / delete []
exactly on the line where 'delete array;' is. I tried 'delete []array' too, but that's just "1 not-freed blocks" too then! If somebody could explain me the proper way it would be much appreciated.
EDIT:
So using:
for (int i = 0; i < size; i++) {
delete array[i];
}
delete[] array;
is working probably fine. It is working in one of my classes (I have two similar) the other still reports some small leak. I would think it's just a minor bug somewhere, but valgrind still points to the line where
array = new Elem* [size];
stands.
EDIT2:
I solved this as well, thank you for your exhausting contribution!!
You need:
delete [] array;
Because it's an array.
I just noticed your note that you tried this too - it's the proper thing to do so I don't know why you'd still be getting an error.
Edit: This deserves a more thorough explanation.
When you create a pointer using new, the pointer may be to a single element or an array of elements depending on the syntax you use. But the pointer type is the same in both cases! The compiler relies on you to know what the pointer points to and treat it accordingly.
Elem ** single = new Elem*; // pointer to one pointer
single[0] = new Elem; // OK
single[1] = new Elem; // runtime error, but not compile time
Elem ** array = new Elem* [2]; // pointer to array of pointers
array[0] = new Elem; // OK
array[1] = new Elem; // OK
When you delete a pointer, the destructor is called for the object it points to or for each element of the array. But since the pointer type is the same in each case, the compiler relies on you to give it the proper syntax so it knows what to do.
delete single;
delete [] array;
In your case the elements of the array are pointers also, and pointers don't have destructors. That means those pointers won't be deleted and will become memory leaks if you don't delete them first. You were correct to have a loop to delete them individually before the final delete.
You should free everything in the array (if dynamically allocated) and then free the array itself.
for (int i = 0; i < size; i++) { // only free inside if dynamically allocated - not if just storing pointers
delete array[i];
}
delete[] array; // necesarry
The syntax for deleting an array is like this:
delete[] array;
Your for loop to delete the objects pointed to by the elements of the array is fine. The deletion of the array itself is the only problem. You need both the for loop and then the delete[] to dispose of the array itself.
for (int i = 0; i < size; i++) {
delete array[i];
}
delete[] array;
I suspect that you have tried using the for loop, or the delete[], but not both together. And if when you do that you still have leaks or errors, then you would need to show us the code that allocates the pointers that are elements of the array.
Using std::vector<> instead of an array would mean that you could stop worrying about these nitty gritty details and move to higher level of abstraction.
In this case, you need both.
for (int i = 0; i < size; i++) {
delete array[i];
}
delete[] array;
You call delete exactly once for each time you called new.
Note that although you need to call delete[] array here (because you allocated it with new[]), the delete[] operator does not call the destructors on the objects pointed to by elements of the array. This is because the delete[] operator calls destructors on objects in the array, and your array contains pointers but not objects. Pointers do not themselves have destructors.