I try to clean the memory to delete pointers. But the last instruction (delete array[i]) generate this error :
pointeurs-tableau(14994,0x110a67600) malloc: *** error for object 0x7ff7bb760760: pointer being freed was not allocated
But I don't know why.
#include <iostream>
#include <random>
#include <ctime>
using namespace std;
int main()
{
default_random_engine gen(time(0));
uniform_int_distribution<> dis(1, 100);
const int max = 20;
int* array[max];
// un tableau normal
int val[max];
for (int i = 0; i < max; i++) {
val[i] = dis(gen);
}
for (int i = 0; i < max; i++)
{
array[i] = &val[i];
}
//... modifying function on the array
// show the array
for (int i = 0; i < max; i++) {
cout << val[i] << " ";
}
// deleting pointeurs (problematic !!!!)
for (int i = 0; i < max; i++)
{ delete array[i];}
delete[] array;
return 0;
}
Could you help me, please?
delete operator must be used only on a dynamically allocated memory (with the new).
In your case you have an array int val[max]; with automatic storage duration. And array of pointers int* array[max]; also with automatic storage duration.
Automatic storage duration means memory for arrays int val[max]; and int* array[max]; will be allocated when execution enter in the scope they declared and will be freed when execution lives the scope (at your case main function).
But when you trying to call delete array[i]; you force compiler to attempt clear element from int val[max] onto which array[i] pointing to. But it can't do that because this value never have been allocated on the heap with new.
// Edit
As you mentioned in comment to this answer you added changes to your code:
int **array = new int*[max];
for (int i=0; i < max; i++) {
array[i] = new int;
}
An still have the same error;
The reason behind it most likely is that you still have this cycle
for (int i = 0; i < max; i++) {
array[i] = &val[i];
}
int** array; item: array[i] - is a pointer.
You allocated memory on the heap and stored address of this memory into that pointer:
array[i] = new int;
Lets say new int; returned address ADDRESS_FROM_HEAP
Then you took address of int val[max]; by &val[i] and assigned it to the pointer array[i] = &val[i];
Lets say &val[i] equal to ADDRESS_FROM_STACK
Then you trying to delete array[i];
But at this moment array[i] == ADDRESS_FROM_STACK;
Not only delete unable to free memory on ADDRESS_FROM_STACK, you also lost ADDRESS_FROM_HEAP and memory by this address will not be freed.
If you would change your loop to this
for (int i = 0; i < max; i++) {
*array[i] = val[i];
}
You will store a COPY of val[i] in the memory pointed by array[i] pointer.
But by looking at your code I can't honestly see why you allocate any memory dynamicly.
If you will just leave code as it is in your original question and just remove all delete statements, it will work just fine.
Related
When I have an array like this:
int* test = new int[50];
for (int i = 0; i < 50; i++)
{
test[i] = dist4(rng);
}
(Filled with random numbers for testing)
I can free the memory like this:
delete[] test;
But when I declare the array like this:
int test[50];
for (int i = 0; i < 50; i++)
{
test[i] = dist4(rng);
}
I can't free the memory with delete or delete[].
What's the proper way of freeing the memory here?
The "dist4" function is just a random number generator:
random_device dev;
mt19937 rng(dev());
uniform_int_distribution<mt19937::result_type> dist4(1,4); // distribution in range [1, 4]
What's the proper way of freeing the memory here?
No need to free memory explicitly using delete or delete[] in the latter case.
Assuming int test[50]; is declared inside a function, it has automatic storage duration and when test goes out of scope it will be automatically destroyed.
The memory will automatically be freed when it does out of scope like any other non-dynamically allocated variable. This is due to automatic storage duration
Write the code like this using a local scope:
void a_function ()
{
// some code
{
int test[50];
for (int i = 0; i < 50; i++)
{
test[i] = dist4(rng);
}
}
// here the space for test will recovered.
// some more code...
}
Consider the code (it has no meaningful purpose):
double* create() {
double *array = new double[100]; // 1)
for(unsigned int i=0; i<100; ++i) array[i] = i;
return array;
}
double reduce(double* array) {
double sum = 0.0;
for(unsigned int i=0; i<100; ++i) sum += array[i];
return sum;
}
int main()
{
double sum = 0.0;
for(unsigned int i=0; i<100; ++i) {
sum += reduce(create());
}
// 2)
// ...
}
Are the arrays created in 1) during the for-loop still on the heap at point 2) i.e. is some memory still being (unnecessarily) occupied at point 2)?
(I know that the example could be more minimalistic but it is really short.)
The array is still in the heap but the pointer to the array is lost. As a result there is a memory leak.
So you should split the calls of the functions introducing a variable that will store the pointer returned from the function create that then you could use the variable to free the allocated array.
That is the array with the dynamic storage duration will be destroyed when the operator delete [] will be called. Or the memory will be freed when the program will finish its execution.
Theoretically, is it enough if I only delete arrays and results but don't delete sub_array inside of arrays in the following code snippet, before return 0; or do I have to first delete all the sub_array before I can safely delete arrays and results.
int main() {
int subarrays, queries;
cin >> subarrays >> queries;
int** arrays = new int* [subarrays]();
int* results = new int[queries];
for (int i = 0; i < subarrays; i++) {
int length;
cin >> length;
int* sub_array = new int[length];
for (int j = 0; j < length; j++) {
int element;
cin >> element;
sub_array[j] = element;
}
arrays[i] = sub_array;
}
for (int i = 0; i < queries; i++) {
int query_from, arr_index;
cin >> query_from >> arr_index;
results[i] = arrays[query_from][arr_index];
}
for (int i = 0; i < queries; i++) {
cout << results[i] << endl;
}
return 0;
}
You shouldn't delete sub_array because the buffer it points to is stored in arrays[n]. As the only way you could delete sub_array is inside the block scope it was declared (which is the for loop), if you do delete it then arrays[n] will be a dangling pointer (a pointer that points to a freed or invalid memory block) and dangling pointers are evil.
What you should do about arrays and sub_array is when they are not needed anymore, you first iterate through all elements of arrays, deleting each one of them and after this, delete arrays itself. Something like:
// when you are done with them
for(auto i = 0; i < subarrays; i++)
{
delete[] arrays[i];
}
delete[] arrays;
As a side-note you should consider using smart pointers in this code.
Yes, you have to first delete all the sub_array before I can safely delete arrays and results to prevent memory leak.
You can employ a loop to go through the sub-arrays in the array.
My question arises from this answer.
In the comments he mentions that I should delete the allocated dynamic 2D array in the reverse order.
However I did not understand much why this should be done. Here is the code:
//intialising array
int size = 10000;
double **array = new double[size];
for(int i = 0; i < size; i++)
array[i] = new double[size];
//conventional de-initialise
for(int i = 0; i < size; i++)
delete[] array[i];
delete[] array;
//reverse de-initialise
for(int i = size - 1; size >= 0; i--)//notice reverse order here
delete[] array[i];
delete[] array;
So my question is, is there any significant difference between the 2 methods of de-allocating a 2D array?
In your example there's no difference - you create 100K pointers, and then allocate memory for each. It doesn't matter how you allocate/deallocate memory and assign it to pointers array.
However your question is about why reverse deallocation was in another post, and opposite to your example it matters - counter variable is reused to countdown from last allocated object down to 0, when new memory allocation failed. If deallocating other direction you'd need additional variable there:
try
{
array = new double*[size];
// Don't shadow counter here.
for(counter = 0; counter < size; counter++)
{
array[counter] = new double[size];
}
}
catch(std::bad_alloc)
{
// delete in reverse order to mimic other containers.
for(--counter; counter >= 0;--counter)
{
delete[] array[counter];
}
delete[] array;
I've been trying to make a program that adds 2 arrays of different size. But I would like to know to to dynamically increase the array size capacity? Ex: array[4] then upgrade the size to 2 to make array[6];?
EDIT: WIthout using vectors
I tried creating a new ptr but it does not work. I get the error: Read only variable is not assignable.
int *ptr2 = new int[a2.size];
// new ptr2 copies ptr1
for (int i=0; i<(a1.size); i++) {
ptr2[i] = a1.ptr[i];
}
// we want ptr1 to point to ptr2
for (int i=0; i<(a2.size); i++) {
ptr2[i] += a2.ptr[i];
}
delete [] a1.ptr;
a1.ptr=ptr2;
You can't change the size of the array, but you don't need to. You can just allocate a new array that's larger, copy the values you want to keep, delete the original array, and change the member variable to point to the new array.
Allocate a new[] array and store it in a temporary pointer.
Copy over the previous values that you want to keep.
Delete[] the old array.
Change the member variables, ptr and size to point to the new array and hold the new size.
int* newArr = new int[new_size];
std::copy(oldArr, oldArr + std::min(old_size, new_size), newArr);
delete[] oldArr;
oldArr = newArr;
#include<bits/stdc++.h>
using namespace std;
main(){
int *p = new int[5]; // locate memory in heap
int *q = new int[10];// locate memory in heap
for(int j=0; j<5;j++)
p[j] = j;
for(int i=0; i<5;i++)
q[i] = p[i];
delete []p;//Delete the old array 'p'
p = q; // Assign the pointer of 'q' to 'p'
q = NULL; // delete the location of pointer 'q'
return 0;
}
It may be late too answer but i'll explain some things to you..
Array Size cannot be increase because of contiguous memory allocation in the memory.
For Example => The address of the every location is
arr[5] => [2001,2002,2003,2004,2005]
Now, The main problem is if you allocate it to arr[10] so, as we don't know the next location 2006 will be free .
because array need to be in contiguous so, we won't be able to allocate memory
From my Suggestions use Vector or use dynamic Memory allocation in Cpp
int *old = new int[5];
int *nw = new int[10];
for (size_t i = 0; i < sizeof(old); i++)
nw[i] = old[i];
delete []old;
old = nw;
nw = NULL;
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p,*q;
int i;
p=(int *)malloc(5*sizeof(int));
p[0]=3;p[1]=5;p[2]=7;p[3]=9;p[4]=11;
q=(int *)malloc(10*sizeof(int));
for(i=0;i<5;i++)
q[i]=p[i];
free(p);
p=q;
q=NULL;
for(i=0;i<5;i++)
printf("%d \n",p[i]);
return 0;
}