How do I deallocate this type of 3D array in c++? I have a class that has a int*** volume as a member and I filled it this way..
volume = new int**[xSize];
for(int i =0; i<xSize; i++)
{
volume[i] = new int*[ySize];
for(int j =0; j<ySize; j++)
{
volume[i][j] = new int[zSize];
for(int k = 0; k<zSize;k++)
{
volume[i][j][k] = 0;
}
}
}
You just reverse your actions (other than the filling of the array)
for(int i =0; i<xSize; i++)
{
for(int j =0; j<ySize; j++)
{
delete[] volume[i][j];
}
delete[] volume[i];
}
delete[] volume;
If you can, avoid manual dynamic memory management in the first place. E.g. using std::vector:
typedef std::vector<int> Vec1D;
typedef std::vector<Vec1D> Vec2D;
typedef std::vector<Vec2D> Vec3D;
Vec3D volume(xSize, Vec2D(ySize, Vec1D(zSize, 0)));
As pointed out in the comments, Boost.MultiArray is a convenient alternative.
You need to recursively iterate through all levels of the structure the same way as above (except the innermost level), and delete each element in reverse order compared to their allocation:
for(int i =0; i<xSize; i++)
{
for(int j =0; j<ySize; j++)
{
delete[] volume[i][j];
}
delete[] volume[i];
}
delete[] volume;
In reverse.
You need the same loop structure, but for every new[], you need a delete[] instead, and now nested stuff must occur before outer stuff.
So:
int **x = new int*[M];
for (i = 0; i < M; i++)
{
x[i] = new int[N];
}
becomes:
for (i = 0; i < M; i++)
{
delete [] x[i];
}
delete [] x;
Easy - Just do the steps in reverse
i.e. delete all those volume[i][j] that you have created
Then volume[i] for all i values
Then volume.
It is a bit like losing your keys - you just need to retrace your steps!
The general rule is this: you need to have one matching delete[] for each and every new[]. You seen to have one instance of new int**[], xSize instances of new int*[], and ySize instances of new int[].
So, you might free them all thus:
for(int i =0; i<xSize; i++)
{
for(int j =0; j<ySize; j++)
{
delete[] volume[i][j];
}
delete volume[i];
}
delete[] volume;
Related
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.
I'm trying to create two dimensional array and assign objects into it. What's important is, that I want to do this using POINTERS. I want to achieve it like this:
Create pointer which will point to array of pointers.
Having array pointers I create next 10 cells in memory for example to store there individual object.
This is my code:
I create basic pointer for storing the address for array of pointers:
SpecialPoint **arrayOfPointsOnTheMap = NULL;
Next I initialize this array:
arrayOfPointsOnTheMap = new SpecialPoint*[size];
And then create cells in memory:
for (int i = 0; i < szer; i++) {
arrayOfPointsOnTheMap[i] = new SpecialPoint[wys];
}
And for the end I want to assign object to this newly created array:
SpecialPoint *pontInTable;
for (int i = 0; i < szer; i++) {
pontInTable = arrayOfPointsOnTheMap[i];
for (int j = 0; j < wys; j++) {
pontInTable[j] = new SpecialPoint();
}
}
But I get error when trying to create new object int array. I'm a little confused about it. Can anyone help?
What you want to do in the assignment part is not very clear so I will answer based on my best guess. Let`s say your class is as follows:
class SpecialPoint
{
public:
int x;
int y;
SpecialPoint(int xx, int yy)
{
x=xx;
y=yy;
}
SpecialPoint()
{
x=0;
y=0;
}
};
Then you can use the following code to create and initialize your 2d array:
int size = 4;
int wys = 3;
SpecialPoint** arrayOfPointsOnTheMap = new SpecialPoint*[size];
for(int i = 0; i < size; i++)
{
arrayOfPointsOnTheMap[i] = new SpecialPoint[wys];
} // you have your array at that point
SpecialPoint fakePoint(5,6); // create a special point
for(int i=0; i < size; i++)
{
for(int j=0; j < wys; j++)
{ // Assign your special point instance to all the array cells.
arrayOfPointsOnTheMap[i][j] = fakePoint;
}
}
After you are done with the array, do not forget to clean memory using:
for(int i = 0; i < size; i++) {
delete [] arrayOfPointsOnTheMap[i];
}
delete [] arrayOfPointsOnTheMap;
Good luck!
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));
So I know multiple dimensions/arrays can get confusing, but how do I delete these types of arrays properly? I know the syntax, but adding multiple dimensions/pointers gets tricky. Here's some snippet code:
//FIRST PROBLEM
//function to add an item to a pointer array
//due to problems in adding something directly, I created a temp
//temp is not necessary if there's a way without it
int y = 6;
int x = 5;
int *myList = new int[x];
void List::add(int newInt)
{
void List::add(int newInt){
int *temp = new int[x+1];
temp = myList;
temp[x+1] = newInt;
delete [] myList;
int *myList = temp;
}
//SECOND PROBLEM----tricky multidimensional
// not getting any errors, but not sure if done properly
int x;
int y;
int** myMatrix;
cout << "How many rows?" << endl;
cin >> x;
myMatrix = new int*[x];
cout << "How many columns?" << endl;
cin >> y;
for (int i=0; i<x; i++)
myMatrix[i] = new int[y];
for(int i=0; i<10; ++i){
for(int j=0; j<10; ++j){
myMatrix[i][j] = rand();
}
for(int i = 0 ; i < x ; ++i)
{
for(int j = 0 ; j < col ; ++j){
// delete[] myMatrix[i][j]; (tried this method, did not work)
}
delete[] myMatrix[i];
}
delete[] myMatrix;
//looked around for examples, but were all different enough to not help
//
// delete[] myMatrix[i][j]; (tried this method, did not work)
The code you have here
myMatrix[i][j] = rand();
doesn't allocate any new heap memory for myMatrix[i][j] (which is of a non pointer type, but a simple int BTW), but just assigns the result of rand() as a value there.
Thus it's not necessary/wrong, you ever call delete for it.
You only call delete/delete[] as counterparts of new/new[] in the reverse order as they were allocated.
Further, to get redeemed from struggling with memory management, I'd seriously recommend using a c++ standard container like std::vector<std::vector<int>> myMatrix; instead of managing raw pointers.
//gives the error expecting a declaration
int** my_array;
for (int i=0; i<200; i++)
{
my_array[i]= new int [200];
}
//initialize array with zeroes
for (int i = 0; i<200; i++)
{
for (int j = 0; j<200; j++)
{
my_array[i][j] =0;
}
}
In brief:
The 2D array is declared globally
It is initialized in the main. The main calls a function that saves 0's or 1's in specific cells of the array
The array is then printed by the main
Also advice whether the flow is correct?
If you want an array of an array of 200 bools, you could use std::array and std::bitset.
#include <bitset>
#include <array>
//...
std::array<200, std::bitset<200>> my_array;
Second, your code, even if you fix the syntax error is wrong. You would need to create my_array this way:
int** my_array;
//...
my_array = new int * [200];
for (int i = 0; i < 200; ++i )
my_array[i] = new int [200];
Then somewhere you have to delete this memory:
for (int i = 0; i < 200; ++i )
delete [] my_array[i];
delete [] my_array;
An alternate that creates a contiguous block and uses only two calls to new[]:
my_array = new int * [200];
int *pool = new int [200*200];
for (int i = 0; i < 200; ++i, pool += 200 )
my_array[i] = pool;
Then somewhere you have to delete this memory:
delete [] my_array[0];
delete [] my_array;
However I advise you use a container such as the std::array, std::bitset, std::vector, etc. instead of the int** approach.
Regarding your syntax error, it's probably due to something before the code you have shown.
The shown code,
int** my_array;
for (int i=0; i<200; i++)
{
my_array[i]= new int [200];
}
//initialize array with zeroes
for (int i = 0; i<200; i++)
{
for (int j = 0; j<200; j++)
{
my_array[i][j] =0;
}
}
compiles fine as the body of a function.
Regarding the logic, which is incorrect and which uses troublesome constructs,
do this:
auto my_array = vector<vector<bool>>( 200, vector<bool>( 200 ) );
where vector is std::vector from the <vector> header.
This avoids the raw pointers, the new-ing`, the loops, etc., all that you find problematic.
Alternatively you can declare it like this:
vector<vector<bool>> my_array( 200, vector<bool>( 200 ) );
Note that a global variable is usually troublesome, best avoided.