c++ deallocate 2d int array error - c++

I get very frustrating error in following piece of code. Thats my array.
int **tab2 = new int*[3];
I allocate this like it.
for(i = 0; i < 10; i++) {
tab2[i] = new int[3];
tab2[i][0] = 40;
tab2[i][1] = 10;
tab2[i][2] = 100;
}
Then after using it i want to destroy it.
for(i = 0; i < 10; i++) {
delete [] tab2[i];
}
delete [] tab2;
And this causes core dump every single time. I tried many different ways to destroy it and every time get this error. What im making wrong here ?

This
int **tab2 = new int*[3];
does not do what you think it does.
You want an array that will contain TEN (10) pointers, each to an array of THREE ints.
new int*[3] is an array that contain THREE pointers.
What you want is this (live at coliru):
#include <iostream>
int main() {
int **tab2 = new int*[10];
for(int i = 0; i < 10; i++) {
tab2[i] = new int[3];
tab2[i][0] = 40;
tab2[i][1] = 10;
tab2[i][2] = 100;
}
for(int i = 0; i < 10; i++) {
delete [] tab2[i];
}
delete [] tab2;
}

With
int **tab2 = new int*[3];
you allocate an array of pointers of size 3. But than with
for(i = 0; i < 10; i++) {
tab2[i] = new int[3];
//...
}
you access it with up to index 9. That will surely go wrong.
The deletion process looks fine to me. To fix it, you should allocate an array of pointers with size 10instead of 3, e.g.
int **tab2 = new int*[10];

Looks like what you're trying to do is to create an N by M array, where N is known at runtime and M is fixed (in this case, 3).
Why not just do this?
{
std::array<int, 3> defaults = {{ 40, 10, 100 }};
std::vector<std::array<int, 3>> thing(10, defaults);
}
The vector, thing is automatically deallocated when it goes out of scope, and its size can be set at runtime. You still access the structure in the same way:
thing[1][2] = 3
Manual memory management can be easily avoided by using standard containers and smart pointers. Doing so will keep you code cleaner, and have fewer opportunities for dangling pointers and memory leaks.

Related

Declaring and initializing a global 2D array

//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.

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.

cpp two dimensional dynamic array

I'm using c++ and I want to use two dimensional dynamic array. I tried this:
#include<iostream.h>
using namespace std;
void main(){
int const w=2;
int size;
cout<<"enter number of vertex:\n";
cin>>size;
int a[size][w];
for(int i=0; i<size; i++)
for(int j=0; j<w; j++){
cin>>a[i][j];
}
}
but not worded.
and I tried this:
int *a = new a[size][w];
instead of
int a[size][w];
but not worked!
could you help me plz.
thanks a lot.
The correct approach here would be to encapsulate some of the standard containers, that will manage memory for you, inside a class that provides a good interface. The common approach there would be an overload of operator() taking two arguments that determine the row and column in the matrix.
That aside, what you are trying to create manually is an array of dynamic size of arrays of constant size 2. With the aid of typedef you can write that in a simple to understand manner:
const int w = 2;
typedef int array2int[w];
int size = some_dynamic_value();
array2int *p = new array2int[size];
Without the typedef, the syntax is a bit more convoluted, but doable:
int (*p)[w] = new int [size][w];
In both cases you would release memory with the same simple statement:
delete [] p;
The difference with the approaches doing double pointers (int **) is that the memory layout of the array is really that of an array of two dimensions, rather than a jump table into multiple separately allocated unidimensional arrays, providing better locality of data. The number of allocations is lower: one allocation vs. size + 1 allocations, reducing the memory fragmentation. It also reduces the potential from memory leaks (a single pointer is allocated, either you leak everything or you don't leak at all).
For a dynamic sized array you must dynamically allocate it. Instead of
int *a = new a[size][w];
Use
int** a = new int*[size];
for(int i = 0; i < size; i++)
a[i] = new int[w];
OP is saying he wants to create a 2 dimensional array where one dimension is already known and constant and the other dimension is dynamic.. Not sure if I got it right but here goes:
int main() {
const int w = 2;
int size = 10;
int* arr[w];
for (int i = 0; i < w; ++i)
arr[i] = new int[size];
//do whatever with arr..
//std::cout<<arr[0][0];
for (int i = 0; i < w; ++i)
for (int j = 0; j < size; ++j)
std::cout<<arr[i][j];
for (int i = 0; i < w; ++i)
delete[] arr[i];
return 0;
}
You can not do that in c++, please read about dynamic memory allocation
the code below should work
int* twoDimentionalArray = new [size*w]

Deleting two dimensional array use memory?

I have been working on this program for quite some time. This is just two of the functions extracted that are causing a memory leak that I cant seem to debug. Any help would be fantastic!
vector<int**> garbage;
CODE for deleting the used memory
void clearMemory()
{
for(int i = 0; i < garbage.size(); i++)
{
int ** dynamicArray = garbage[i];
for( int j = 0 ; j < 100 ; j++ )
{
delete [] dynamicArray[j];
}
delete [] dynamicArray;
}
garbage.clear();
}
CODE for declaring dynamic array
void main()
{
int ** dynamicArray1 = 0;
int ** dynamicArray2 = 0;
dynamicArray1 = new int *[100] ;
dynamicArray2 = new int *[100] ;
for( int i = 0 ; i < 100 ; i++ )
{
dynamicArray1[i] = new int[100];
dynamicArray2[i] = new int[100];
}
for( int i = 0; i < 100; i++)
{
for(int j = 0; j < 100; j++)
{
dynamicArray1[i][j] = random();
}
}
//BEGIN MULTIPLICATION WITH SELF AND ASSIGN TO SECOND ARRAY
dynamicArray2 = multi(dynamicArray1); //matrix multiplication
//END MULTIPLICATION AND ASSIGNMENT
garbage.push_back(dynamicArray1);
garbage.push_back(dynamicArray2);
clearMemory();
}
I stared at the code for some time and I can't seem to find any leak. It looks to me there's exactly one delete for every new, as it should be.
Nonetheless, I really wanted to say that declaring an std::vector<int**> pretty much defies the point of using std::vector itself.
In C++, there are very few cases when you HAVE to use pointers, and this is not one of them.
I admit it would be a pain to declare and use an std::vector<std::vector<std::vector<int>>> but that would make sure there are no leaks in your code.
So I'd suggest you rethink your implementations in term of objects that automatically manage memory allocation.
Point 1: If you have a memory leak, use valgrind to locate it. Just like blue, I can't seem to find a memory leak in your code, but valgrind will tell you for sure what's up with your memory.
Point 2: You are effectively creating a 2x100x100 3D array. C++ is not the right language for this kind of thing. Of course, you could use an std::vector<std::vector<std::vector<int>>> with the obvious drawbacks. Or you can drop back to C:
int depth = 2, width = 100, height = 100;
//Allocation:
int (*threeDArray)[height][width] = malloc(depth*sizeof(*threeDArray));
//Use of the last element in the 3D array:
threeDArray[depth-1][height-1][width-1] = 42;
//Deallocation:
free(threeDArray);
Note that this is valid C, but not valid C++: The later language does not allow runtime sizes to array types, while the former supports that since C99. In this regard, C is more powerful than C++.

Dynamically Growing an Array in C++

I have an array of pointers of CName objects. I have the following constructor which initializes my array to size one. Then when I add an object I grow the array by 1 and add the new object. It compiles fine, however when I try to print them I just get segmentation fault error. Can you look and see if I'm doing anything wrong?
//constructor
Names_Book::Names_Book()
{
grow_factor = 1;
size = 0;
cNames = (CName**)malloc(grow_factor * sizeof(CName*));
cNames[0] = NULL;
}
void Names_Book::addCName(CName* cn)
{
int oldSize = size;
int newSize = size + 1;
CName** newCNames = (CName**)malloc(newSize * sizeof(CName*));
for(int i=0; i<newSize; i++)
{
newCNames[i] = cNames[i];
}
for(int i=oldSize; i<newSize; i++)
{
newCNames[i] = NULL;
}
/* copy current array to old array */
cNames = newCNames;
delete(newCNames);
size++;
}
To have dynamically growable array in C++, you should use std::vector or at least look at its implementation.
There are a few things wrong with this function:
void Names_Book::addCName(CName* cn)
{
int oldSize = size;
int newSize = size + 1;
CName** newCNames = (CName**)malloc(newSize * sizeof(CName*));
for(int i=0; i<newSize; i++)
{
newCNames[i] = cNames[
}
for(int i=oldSize; i<newSize; i++)
{
newCNames[i] = NULL;
}
/* copy current array to old array */
cNames = newCNames; //right here you just leaked the memory cNames was pointing to.
delete(newCNames); // right here you delete the new array you just created using the wrong call.
size++;
}
Near the end you do two things quite wrong. (Commented above.)
Those last two lines should be:
free(cNames);
cNmaes = newCNames;
Also, you should do a realloc rather than slowly copying elements one by one....
With that said, you should use vector.
Don't try to (poorly) rewrite what already exists.
The first loop should be to oldSize:
for(int i=0; i<oldSize; i++)
cNames isn't big enough for newSize.