c++, minify dynamic array by delete [] x[i] - c++

I have a 2D array with size 4 (4 rows). To make the array size 2 (2 rows), can I use following? (for our hw assignment details are not specified and the code should be suitable with common c++ standarts)
I am removing second half of the array.
const int newSize = flightsArraySize/2;
for(int i = newSize-1; i < flightsArraySize-1; i++)
delete [] flights[i];
Or do I have to recreate flights array with size 2?

Supposing that you have created a 2D array using new like this:
int **arr = new int*[rows];
for(int i=0; i<rows; ++i)
arr[i] = new int[cols];
Then to resize it you'd have to do something like:
int newRows = rows/2;
// Create a new array for the right number of rows.
int **newArr = new int*[newRows];
// Copy the rows we're keeping across.
for(int i=0; i<newRows; ++i)
newArr[i] = arr[i];
// Delete the rows we no longer need.
for(int i=newRows; i<rows; ++i)
delete[] arr[i];
// Delete the old array.
delete[] arr;
// Replace the old array and row count with the new ones.
arr = newArr;
rows = newRows;
But seriously, this is all so much easier if you just use vector:
std::vector<std::vector<int>> v(rows);
for(int i=0; i<rows; ++i)
v[i].resize(cols);
v.resize(v.size()/2);

Well, it deallocates the memory on which pointed the second half of pointers. But the poiters themselves will stay, the array of pointers will not be shortened.
EDIT
Oh, sorry. It seems as a mistake. If you have code like this:
int **ptr = new int*[4];
for(int i = 0; i < 4; i++)
{
ptr[i] = new int[4];
}
Then when you type
delete[] ptr[3];
It will delete the whole array, so you can create new like this:
ptr[3] = new int[any_number];
Is this what you mean? Sorry, I read too fast...

Related

How many different way exists to define 2D array with pointers in C++?

I try to define a 2D array with C++ with pointers and I don't know how can I define it true? I have some loops in the function and they are start with 1 to n and I want to allocate memory and at the end of function I want to delete allocated memory?
for define it like the following code. please help me to develop it.
int **W;
W = new int* [n];
for (int i=1; i <= n; i++)
W[i] = new int[n];
///////////////////////
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
do some thing!
///////////////////////
for ( int i = 1; i <= n; i++ )
delete [] W[i];
delete W;
For an array of size n, indices start from 0 - (n-1). Thus array[n] is out of bounds.
int **W;
int n = 3;
W = new int*[n];
for (int i = 0; i < n; i++)
W[i] = new int[n];
for (int i = 0; i < n; i++)
delete[] W[i];
delete W;
You have the general idea correct. But there are some errors in the details. C/C++ use 0-based indices to access arrays.
for (int i=1; i <= n; i++)
W[i] = new int[n];
needs to be
for (int i=0; i < n; i++)
W[i] = new int[n];
Similar changes need to be made in the other for statements.
Also, you need to delete W using the array delete operator. Instead of
delete W;
use
delete [] W;
Having said that, you should use std::vector instead of plain old dynamic arrays. With std::vector, you don't have to worry about deallocation of memory. The destructor of std::vector will take care of deallocating memory.
A 2D array of size n x n where each element is initialized to 0 can be defined simply as:
std::vector<std::vector<int>> array(n, std::vector<int>(n, 0));

declare and delete this version of a 2D array in c++

int *array[10];
for(int i = 0; i < 10; i++)
array[i] = new int[10];
//...
void passFunc(int *a[10]) //array containing pointers
{
//...
}
passFunc(array);
Im trying to figure out how to declare and delete this version of a 2D array. I started using int ** array, but in order to make one section of code easier, I need to switch to *[]. Can anyone help me out?
I have tried compiling my actual code (the above code is just an example), which looks like this:
int* filedata[LENGTH] = new int*[LENGTH]; //ERROR: array must be initialized with brace- enclosed identifiers.
EDIT:
Thanks!
Something like that
int** array = new int*[sizeX];
for(int i = 0; i < sizeX; ++i)
array[i] = new int[sizeY];
To delete
for(int i = 0; i < sizeX; ++i)
delete [] array[i];
delete [] array;
If I have understood correctly what you want then the allocation and deallocation will look as
int ** filedata = new int * [LENGTH];
for ( int i = 0; i < LENGTH; i++ ) filedata[i] = new int [LENGTH];
//...
for ( int i = 0; i < LENGTH; i++ ) delete [] filedata[i];
delete [] filedata;
Alternate version to the ones given:
int** array = new int*[sizeX];
int *pool = new int[sizeX * sizeY];
for(int i = 0; i < sizeX; ++i, pool += sizeY)
array[i] = pool;
To delete:
delete [] array[0];
delete [] array;
The advantage of using this is:
Only two calls to new[] and delete[] are required, regardless of the number of columns. In the previous answer, the number of calls to new and delete depend on the number of columns. This reduces fragmentation, and also will probably give you a speed increase if the number of columns is very large.
The data is contiguous. You can access any element in the 2d array from any other element using a simple offset.
The disadvantage is that the number of columns for each row needs to be the same, otherwise it becomes very difficult to maintain.

Deleteing 2D array correctly?

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;

dynamically allocating atwo dimensional array where each row contains variable number of elements & freeing it in c++

How can I dynamically allocate a two dimensional array where each row contains variable element? How can I free this memory?
Actually you probably want a vector of vectors, something like this:
std::vector<std::vector<int> > vector_2d;
This way you'll benefit from the automatic memory management of the vector rather than having to manually manage the memory of an array of pointers to arrays of data.
You would need need to use pointers:
int ** a;
a = new (int*)[5];
for(int i = 0; i<5; i++)
{
a[i] = new int[x]; //where x is the size of this row
}
Something like this should work, but I didn't test it.
Just for the sake of completeness:
int ** a;
a = new (int*)[5];
for(int i = 0; i<5; i++)
{
a[i] = new int[x]; //where x is the size of this row
}
for(int i = 0; i<5; i++)
{
delete[] a[i];
}
detete[] a;

Using dynamic multi-dimensional arrays in c++

I am making a C++ program that checks if given aray is a latin square. I need to use a dynamic multi-dimensional array that stores given latin square. But I cant pass the array to a function that does the checking...
Currently I have such code for calling the function:
int squaretest(int **p, int n, int sum) {
//some code
};
And this code is for creating the array:
int main() {
//some code. n - length of one row, sum - sum of elements in one row.
int a;
int **lsquare;
lsquare = new int*[n];
for (int i=0;i<=n-1;i++) for (int j=0;j<=n-1;j++) {
cin >>a;
lsquare[i][j] = a;
}
blocktest(lsquare,n,sum);
//some code
};
The code compiles (i am using Geany IDE and G++ compiler) but when I run it in terminal, after the first imput, that has to be stored in block[0][0] I get Segmentation fault error. What's wrong with my code and what is the correct sollution?
To be able to do that.. You actually need to do this:
int **lsquare = new int*[n];
for (int i=0; i<n; ++i)
lquare[i] = new int[n];
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
cin >> lsquare[i][j];
blocktest(lsquare,n,sum);
The better system would be to do:
int *lsquare = new int[n*n];
for (int i=0; i<n; ++i)
for (int j=0; j<n; ++j)
cin >> lsquare[i + j*n];
blocktest(lsquare, n, sum);
You forgot to allocate memory for second dimension of the matrix.
int **lsquare;
lsquare = new int*[n];
for (int i=0; i<n; ++i){
lsquare[i] = new int[n];
....}
nobody writes
for (int i=0;i<=n-1;i++){...}
Do instead
for (int i=0; i<n; ++i){...}
You have an array of pointers in lsquare.
You might want to just do something like:
lsquare = new int[n * n];
That way you can then fill in this square, but the type is then:
int *lsquare
What you are actually creating an array of arrays. Not only do you need to allocate the array of arrays using new, but also you must allocate all n arrays. You'll want to have the outer loop of your nested for loop allocate each of the n sub-arrays.
lsquare = new int*[n];
for (int i=0;i<=n-1;i++)
{
lsquare[i] = new int[n];
for (int j = 0;j<=n-1;j++)
{
//...
You made yourself a pointer pointer that can be used as a matrix, allocated one row for it, then proceeded to act like you'd allocated an entire n*n matrix. You will indeed get a segfault if you run that.
You need to allocate enough space for n*n elements, not just n of them.
A less error-prone solution might be to use a std::vector of std::vectors.
You have to allocate space for the second dimension too, add this after you allocate lsquare:
for(int i = 0; i < n; ++i)
{
lsquare[i] = new int[n];
}