When I tried to delete a 2-D array in C++ , it caused an error in Visual Studio 2017:
HEAP CORRUPTION DETECTED: after Normal block (#530965) at 0x0ACDF348.
CRT detected that the application wrote to memory after end of heap buffer.
The code is below:
const int width = 5;
const int height = 5;
bool** map = new bool*[height];
for (int i = height; i >= 0; --i) {
map[i] = new bool[width];
}
for (int i = height; i >= 0; --i) {
delete[] map[i];
}
delete[] map; // error occurs here
What's wrong with the code please?
You're getting out of the bound of the array; which leads to UB. Note that the range is [0, height), the elements are numbered 0, …, height - 1.
Change the two for loop from
for (int i = height; i >= 0; --i) {
to
for (int i = height - 1; i >= 0; --i) {
PS: In most cases we don't need to use raw pointers and new / delete expression manually, you can just use array (not with raw pointer), or std::vector and std::array, or smart pointers instead.
Related
I have an array called int **grid that is set up in Amazon::initGrid() and is made to be a [16][16] grid with new. I set every array value to 0 and then set [2][2] to 32. Now when I leave initGrid() and come back in getGrid() it has lost its value and is now 0x0000.
I don't know what to try, the solution seems to be really simple, but I'm just not getting it. Somehow the data isn't being kept in g_amazon but I could post the code.
// Returns a pointer to grid
int** Amazon::getGridVal()
{
char buf[100];
sprintf_s(buf, "Hello %d\n", grid[2][2]);
return grid;
}
int Amazon::initGrid()
{
int** grid = 0;
grid = new int* [16];
for (int i = 0; i < 16; i++)
{
grid[i] = new int[16];
for (int j = 0; j < 16; j++)
{
grid[i][j] = 0;
}
}
grid[2][2] = 32;
return 0;
}
int **grid;
g_amazon = Amazon::getInstance();
g_amazon->initGrid();
grid = g_amazon->getGridVal();
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
int index;
index = (width * 4 * i) + (4 * j);
int gridval;
gridval = grid[i][j];
lpBits[index] = gridval;
lpBits[index + 1] = gridval;
lpBits[index + 2] = gridval;
}
}
It crashes when I run it at the line where sprintf_s prints out [2][2] and it also crashes when I get to gridval = grid[i][j] because it's at memory location 0x000000.
The variable
int** grid
in the initGrid() function is a local variable. Edit** When the function returns the variable is popped off the stack. However, since it was declared with the new operator the memory still exists on the heap; it is simply just not pointed to by your global grid variable.
#Dean said in comment:
I have grid as an int** grid; in class Amazon {}; so shouldn't it stay in memory or do I need a static var.
That is the problem:
local int **grid; on Amazon::initGrid::
is masking
member int **grid; on Amazon::
as the first context has higher priority in name lookup.
So initGrid() allocates memory referenced only by a local pointer. That pointer no longer exists when you return from this function, Amazon::grid was never touched on initialization and you're also left with some bad memory issues.
So, as commented by #Remy-Lebeau, I also suggest
Consider using std::vector> or std::array, 16> instead. There is no good reason to use new[] manually in this situation.
I have made a class that's supposed to make a symmetric toeplitz matrix (see here). The implementation of the class is shown here
class toeplitz{
private:
int size;
double* matrix;
public:
toeplitz(const double* array, const int dim){
size = dim;
matrix = new double(size*size);
for(int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
int index = std::abs(i - j);
matrix[i*size + j] = array[index];
}
}
}
~toeplitz(){
delete[] matrix;
}
void print() const{
//loop over rows
for (int i = 0; i < size; i++){
//loop over colums
for (int j = 0; j < size; j++){
double out = matrix[i*size + j];
std::cout << std::setw(4) << out;
}
//start new line for each row
std::cout << "\n";
}
}
};
I can't see what's wrong with this, but when I try and use this in a simple test function, I get malloc errors. The main function I have is
int main(){
double array[] = {0,1,1,2};
int len = sizeof(array)/sizeof(array[0]);
std::cout<<"length of array " << len << std::endl;
toeplitz tp = toeplitz(array, len);
tp.print();
}
It compiles and runs when I leave out the tp.print() line, but when I add this line I get error
test_toeplitz(8747,0x7fffdbee63c0) malloc: *** error for object 0x7fb119402788:
incorrect checksum for
freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
I cannot figure out why this is. I've looked at the other questions about this on here but I can't tell how they relate to what I've done. As I understand it has to do with either double freeing memory or trying to modify memory after it's been freed, but I can't see where my code is doing that. Any insight into what's going on would be appreciated.
You stumbled on the classical:
matrix = new double(size*size);
which allocates a double worth size*size when you wanted to do:
matrix = new double[size*size];
to allocate an array of the proper size. So you get undefined behaviour. Sometimes it works sometimes not depending on the memory configuration.
Since you're using C++, I suggest you use std::vector<double> or Eigen matrix template, and drop C arrays forever (no more memory leaks, no more failed allocations, possible boundary checking, only advantages)
hey I want to allocate some memory for a 2D array and free it later in C++
I want to do this as I am getting an Error in my program " EXPRESSION MUST HAVE A CONSTANT VALUE.
int x = height;
int y = width;
int pixelArray[x][y];
Thank you.
I'm using Visual Studio 2013
The naive approach is to allocate one array to contain row pointers, and then allocate every single row, but this can lead to poor performance of your array due to memory locality. It also cannot be used in the same way as a fixed-size 2D array, which is contiguous in memory.
So what you can do is allocate one block of integers to hold all the data, and one array of pointers to index it.
int ** my_array = new int*[ x ];
my_array[0] = new int[ x * y ];
for( int i = 1; i < x; i++ )
{
my_array[i] = my_array[i-1] + y;
}
To clean up, you do this:
delete [] my_array[0];
delete [] my_array;
You should consider wrapping this functionality into a simple class, since it is maintaining more than one pointer.
Since x and y are variables, you have to dynamically allocate the array using new. You can initialize a 2D array as follows:
int ** pixelArray = new int*[x];
for (int i = 0; i < x; i++) {
pixelArray[i] = new int[y];
}
And you dispose of it in the following way:
for (int i = 0; i < x; i++) {
delete[] pixelArray[i];
}
delete[] pixelArray;
I am new in C++ programing so I need a help about 2D arrays. Is it possible to create complex array from two real array with two for loops?I was trying to do that in my code but...I do not know how to do that.
Thanks for help!
This is my code::
#include <iostream>
#include <fstream>
#include <complex>
#include <cmath>
using namespace std;
int const BrGr = 15, BrCv = BrGr + 1, BrSat = 24;
//(BrCv=number of nodes,BrSat=number of hours)
int main()
{
// Every array must be dynamic array.It is a task.Is this correct way?
auto *Ipot = new double[BrCv - 1][BrSat];
auto *cosfi = new double[BrCv - 1][BrSat];
auto *S_pot = new complex<double>[BrCv - 1][BrSat];
auto *I_inj = new complex<double>[BrCv - 1][BrSat];
auto *V_cvo = new complex<double>[BrCv][BrSat];
ifstream reader("Input.txt");
if (reader.is_open())
{
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
reader >> Ipot[i][j];
}
}
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
reader >> cosfi[i][j];
}
}
}
else cout << "Error!" << endl;
reader.close();
// Here i want to create 2D array of complex numbers - Is this correct way?
// Also in same proces i want to calculate a value of S_pot in every node for every hour
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
S_pot[i][j] = complex<double>(Ipot[i][j]*cosfi[i][j],Ipot[i][j]*sqr(1-pow(cosfi[i][j],2)));
}
}
// Here i give a value for V_cvo in nodes for every single hour
for (int i = 0;i < BrCv;i++)
{
for (int j = 0;j < BrSat;j++)
{
V_cvo[i][j] = 1;
}
}
// Here i want to calculate a value of I_inj in every node for every hour
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
I_inj[i][j] = conj(S_pot[i][j] / V_cvo[i][j]);
}
}
// Here i want to delete all arrays
delete[] Ipot, cosfi, S_pot, I_inj, V_cvo;
system("pause");
return 0;
Note: I'm using double through out these examples, but you can replace double with any type.
To be honest, you probably don't want to use a 2D array.
Creating a 2D dynamically-sized array in C++ is a multi-stage operation. You can't just
double twoDArray [nrRows][nrColumns];
or
auto twoDArray = new double[nrRows][nrColumns];
There are a couple things wrong with this, but the most important is the rows and columns are not a constant, defined at compile time values. Some compilers allow the first, but this cannot be guaranteed. I don't know if any compiler allows the second.
Instead, First you create an array of rows to hold the columns, then you separately create each row of columns. Yuck.
Here's the set up:
double * arr[] = new double*[nrRows]; // create rows to point at columns
for (size_t index = 0; index < nrRows; index++)
{
arr[index] = new double[nrColumns]; // create columns
}
And here's clean-up
for (size_t index = 0; index < nrRows; index++)
{
delete[] arr[index]; // delete all columns
}
delete[] arr; // delete rows
For your efforts you get crappy spacial locality and the performance hit (Cache miss) that causes because your many arrays could be anywhere in RAM, and you get crappy memory management issues. One screw-up, one unexpected exception and you have a memory leak.
This next option has better locality because there is one big data array to read from instead of many, but still the same leakage problems.
double * arr2[] = new double*[nrRows]; // create rows to point at columns
double holder[] = new double[nrRows* nrColumns]; // create all columns at once
for (size_t index = 0; index < nrRows; index++)
{
arr[index] = &holder[index * nrColumns]; // attach columns to rows
}
and clean up:
delete[] arr2;
delete[] holder;
In C++, the sane person chooses std::vector over a dynamically-sized array unless given very, very compelling reason not to. Why has been documented to death all over SO and the Internet at large, and the proof litters the Internet with hijacked computers serving up heaping dollops of spam and other nastiness.
std::vector<std::vector<double>> vec(nrRows, std::vector<double>(nrColumns));
Usage is exactly what array users are used to:
vec[i][j] = somevalue;
This has effectively no memory problems, but is back to crappy locality because the vectors could be anywhere.
But...!
There is a better method still: Use a One Dimensional array and wrap it in a simple class to make it look 2D.
template <class TYPE>
class TwoDee
{
private:
size_t mNrRows;
size_t mNrColumns;
vector<TYPE> vec;
public:
TwoDee(size_t nrRows, size_t nrColumns):
mNrRows(nrRows), mNrColumns(nrColumns), vec(mNrRows*mNrColumns)
{
}
TYPE & operator()(size_t row, size_t column)
{
return vec[row* mNrColumns + column];
}
TYPE operator()(size_t row, size_t column) const
{
return vec[row* mNrColumns + column];
}
};
This little beastie will do most of what you need a 2D vector to do. You can copy it, you can move it. You can crunch all you want. Jay Leno will make more.
I jumped directly to the templated version because I'm stumped for a good reason to explain class TwoDee twice.
The constructor is simple. You give it the dimensions of the array and it builds a nice, safe 1D vector. No muss, no fuss, and No Zayn required.
The operator() functions take the row and column indices, do a simple bit of arithmetic to turn the indices into a single index and then either return a reference to the indexed value to allow modification or a copy of the indexed value for the constant case.
If you're feeling like you need extra safety, add in range checking.
TYPE & operator()(size_t row, size_t column)
{
if (row < mNrRows && column < mNrColumns)
{
return vec[row* mNrColumns + column];
}
throw std::out_of_range("Bad indices");
}
OK. How does the OP use this?
TwoDee<complex<double>> spot(BrCv - 1, BrSat);
Created and ready to go. And to load it up:
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
Spot(i,j) = complex<double>(7.8*Ipot(i,j),2.3*cosfi(i,j));
}
}
Declaring a dynamic 2D array for a premitive type is the same as for std::complex<T>.
Jagged array:
complex<int> **ary = new complex<int>*[sizeY];
//run loop to initialize
for (int i = 0; i < sizeY; ++i)
{
ary[i] = new complex<int>[sizeX];
}
//clean up (you could wrap this in a class and write this in its destructor)
for (int i = 0; i < sizeY; ++i)
{
delete[] ary[i];
}
delete[] ary;
//access with
ary[i][j];
//assign index with
ary[i][j] = complex<int>(int,int);
It's a little heavier weight than it needs to be, and it allocates more blocks than you need.
Multidimensional arrays only need one block of memory, they don't need one block per row.
Rectangular array:
complex<int> *ary = new complex<int>[sizeX * sizeY];
//access with:
ary[y*sizeX + x]
//assign with
ary[y*sizeX+x] = complex<int>(int,int);
//clean up
delete[] ary;
Allocating just a single contiguous block is the way to go (less impact on allocator, better locality, etc But you have to sacrifice clean and nice subscripting.
CASE1:
int nrows=5;
int ncols=10;
int **rowptr;
rowptr=new int*;
for(int rows=0;rows<nrows;rows++) {
for(int cols=0;cols<ncols;cols++) {
*rowptr=new int;
}
}
CASE2:
int nrows=5;
int ncols=10;
int **rowptr;
for(int rows=0;rows<nrows;rows++) {
rowptr=new int*;
for(int cols=0;cols<ncols;cols++) {
*rowptr=new int;
}
}
I am able to insert and print values using both ways. What is the difference in initializations?
What is the difference?
#1 just allocates memory enough to hold a integer pointer and not an array of integer pointers.
#2 Causes a memory leak by just overwritting the memory allocation of the previous iteration.
I am able to insert and print values using both the ways
Memory leaks and Undefined behaviors may not produce immediate observale erroneous results in your program but they sure are good cases of the Murphy's Law.
The correct way to do this is:
int nrows = 5;
int ncols = 10;
//Allocate enough memory for an array of integer pointers
int **rowptr = new int*[nrows];
//loop through the array and create the second dimension
for (int i = 0;i < nrows;i++)
rowptr[i] = new int[ncols];
You have a memory leak in both cases.
The proper way to initialize such a "2d" array is
int** arr = new int*[nrows];
for (int i = 0; i < nrows; i++)
arr[i] = new int[ncols];
Note however, that it isn't a 2d array as defined by C/C++. It may not, and probably will not, be consecutive in memory. Also, the assembly code for accessing members is different.
In your case, the accessing by indexing is equivalent to *(*(arr+i)+j)
And in the case of a 2d array it's *(arr + N_COLS*i + j) when N_COLS is a compile time constant.
If you want a true 2d array you should do something like this:
int (*arr)[N_COLS] = (int(*)[N_COLS])(new int[N_ROWS * N_COLS])
You'd better use 1d array to manage 2d array
int **x = new int*[nrows];
x[0] = new int[nrows*ncols];
for (int i = 1; i < nrows; i++)
x[i] = x[i-1] + ncols;
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
x[i][j] = 0;
delete [] x[0];
delete [] x;