C++: 2D Dynamic Array allocation causing Visual Studio to crash - c++

I'm fairly new to dynamic arrays, especially mullti-dimensional dynamic arrays and I've scowered StackOverflow and C++ tutorial sites trying to find a fix to my problem, but I can't seem to find any. Anyways I am trying to initialize a 2D dynamic array with values obtained from a text file and I'm experiencing some errors and problems. The numbers are meant to be placed inside the array to form a matrix. But every time I run my code it gives me an "Application.exe has stopped working error".
bool loadMatrix(const char *filename, int **matrix, int& rowCount, int& columnCount);
*matrix = new int[ rowCount * columnCount];
for( size_t currentRow=0; currentRow<rowCount; currentRow++) {
for( size_t currentColumn=0; currentColumn<columnCount; currentColumn++){
//This takes the value from the vector lines<> to be stored in the matrix
int value = stoi(lines[currentRow][currentColumn], 0, 10);
*matrix[currentRow * columnCount + currentColumn] = value;
}
}
it is 100% something to do with the last line in the code above, as all the rest of the code had been given in the assignment skeleton. I have edited and changed the code in every way to try and fix the error. One attempt fixed it, but caused another bug with all elements of the array being overwritten by the last element, as seen below:
matrix[currentRow * columnCount + currentColumn] = &value;
But as you can see, this causes another problem, as now all the values in the matrix are overwritten by the last. As well, the array needs to be updated such that what values are added are accessible outside this function, and the above code won't allow the updated matrix to accessed outside of this function. Below is the output error of the above line of code:
1, 2, 3
4, 5, 6
results as
6, 6, 6
6, 6, 6
I'm not too sure why the first attempt causes this error, but I understand the second attempt is due to some pointer to memory error.
Any ideas on how I could fix this?
Thanks in advance

Related

Creating an unmodifiable 2d array in c++

Quick background, I have some experience with java and currently new to c++.
My question comes from an assignment in which we had to create 4 different magic squares, but for the nature of this particular question they can be any 2d array, so long as they are "exact" in values, only that they appear differently from each one. What I mean by that is if one 2d array looked like:
1 2 3
4 5 6
7 8 9
the next one would be rotated 90 degrees
7 4 1
8 5 2
9 6 3
and so on..
To make the first matrix I simply made a 2d array and created it using the magic square algorithm (irrelevant)
int** square = new int*[size]();
for (int i = 0; i<size; i++) {
square[i] = new int[size]();
}
//set values to square .. irrelevant to show, could be anything
//way down the code
int** secondSquare = square;
For the second third and fourth ones all I would need to do is rotate the previous one to get the next rotated square. My problem however wasn't that I could not flip the arrays, but that while trying to flip them the values for the first square were also changing.
Obviously this is more of a problem about being able to access the data in square and not change it while trying to add them to secondSquare.
I tried making it so square was a modifiable pointer w constant unmodifiable values.
const int** square = new int*[size];
The problem with this is that I have to assign values after to square so this cannot be done. Also when I initialize secondSquare it gives me an error since it is of type int** and not const int**.
Any better ways to handle problems with accessing data without changing values and setting both arrays (or objects really) properly on initialization?
You would do well to avoid using raw pointers and new entirely . That should really come in the advanced section of any C++ course.
Here is one way:
array< array<int,3>, 3> square = {{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }};
square[1][1] = 12; // optional
const auto &c_square = square;
Now c_square is a const accessor of square that you can use later and avoid risk of modifying square.
The problem is int** secondSquare = square; copies the address of the square pointer to secondSquare. So in the end you have two (three, four) pointers pointing to exact same place in memory. Think about it like you have one square created but you try to access it through four different pointers.
What you want to do is to allocate memory for 4 different int** pointers.
To create a 2d array, you would declare it as const:
const int array_2d[3][3] =
{
0, 1, 2,
3, 4, 5,
6, 7, 8
};
In my experience, the better method is to declare it as static const so you are telling the compiler that there is only 1 read only instance:
static const int array_2d[3][3] =
{
0, 1, 2,
3, 4, 5,
6, 7, 8
};
The static allows for the compiler to place the data in a read-only section of the executable and access it directly, rather than copying it from Read-Only to the stack before usage (I've seen compilers emit this kind of code).

Why do I get the segmentation fault error (arrays as elements of classes)?

I have a class called Item that stores an array of a size known at compile time:
class Item
{
int *data;
public:
Item(int array[], int length)
{
std::copy(array, array + length, data); // Line A
}
};
In my example the size equals to 1, but for my project I need greater values as well. Here is a class Box that stores two Items. I don't want to have two arguments in the constructor, so I pass an array of size 2 (since the class can only store 2 Items and each of them stores an array of length 1).
class Box
{
Item *item1;
Item *item2;
public:
Box(int (&array)[2])
{
item1 = new Item(array, 1);
item2 = new Item(array + 1, 1);
}
~Box()
{
delete item1;
delete item2;
}
};
And this is how I create a pointer to a Box object:
int main()
{
int tab[] = {8, 9};
Box *box = new Box(tab);
delete box;
return 0;
}
After running the above piece of code, I got the following error:
Segmentation fault (core dumped).
I debugged it and it turned out that the line A is causing the problem. I also create the Item class in my main function and it doesn't give me any errors.
It seems to me that I'm trying to access some memory outside of my table, but this can't be true - I just want to copy one element of my array. Besides, the c++ compiler wouldn't mind it anyway.
So, what am I doing wrong? How can I fix it?
I'm using the g++ compiler and the -std=c++11 option.
I can use std::array instead, but I'd like to know what mistake am I making just out of curiosity.
Item isn't quite right. When you have:
std::copy(array, array + length, data); // Line A
You're never actually allocating anything for data first - so you're writing into whatever garbage happens to be in that pointer when it's initialized. You need to first do something like:
data = new int[length];
std::copy(array, array + length, data);
Although then you have remember to add a destructor, and copy/move assignment. Even better would be to simply use what the standard provides:
using Item = std::vector<int>;
Besides, the c++ compiler wouldn't mind it anyway.
Just because code compiles doesn't mean it works. Compilation catches a lot of bugs for us, but it can't do everything!
The expression new int(length) only allocates a single int and initializes it to the value of lenght.
You need to use square brackets [] for the size: new int[length].

C++ and recursion with arrays

I've programmed with other languages, but now that I am learning C++, I've found a problem. I am trying to solve a problem with recursion, with a method that takes an array as an argument. I thought about using a public array, maybe, but I can't use the array either way.
From what I've read, it seems to me that it has something to do with the memory. (I thought that, even though it consumes a lot of memory, creating it again with each call would work.)
Here's some code:
static void FindSolution(int row, int column, bool answer[][8][8]) {
for(int i = 0; i < 8; i++)
//Some processing…
bool temp = true;
FindSolution(0, column + 1, answer[row][column] = temp);
}
}
How do I get to actually use the array? Somehow.
The error:
error: array type 'bool [8]' is not assignable
FindSolution(0, column + 1, answer[row][column] = temp);
You have an extra [] on your array. You've declared it as a 3D array, but then you try to assign to it like it is a 2D array. The compiler gets upset because you try to assign a bool value to an array, which is exactly what you are doing:
answer[row][column] = temp;
temp has type bool, but answer[row][column] has type bool[8].
Instead declare the argument without the extra []:
static void FindSolution(int row, int column, bool answer[8][8]) {
You keep incrementing 'column', but you never check it to make sure it doesn't reach 8. When it does reach 8, you're off the end of the array, and you get an error.
There are a few immediate problems with this.
First Problem: Function signature is incorrect
You've declared the third parameter as a 3-dimensional array, but you only want to deal with two dimensions it seems. There are a couple of ways you can redeclare this function to accept a 2D array, for all the options see the accepted answer here. Personally, in this situation I'd go with a template option unless there is a specific reason not to. Something like the following:
template<size_t _rows, size_t _columns>
static void FindSolution(int row, int column, bool (&answer)[_rows][_columns]) {
// todo: Some processing...
}
This allows you to accurately know the size of the array at compile time, of course this won't work so well with dynamically allocated arrays but seeing as you seemed to know the dimensions of the array already at compile time, I figured this wasn't an issue. If it is, check the other ways of passing a 2D array to a function in the link I attached.
Second issue: Recursive call
The second issue is how you're doing your recursive call.
FindSolution(0, column + 1, answer[row][column] = temp);
The result of the assignation of temp to the specific location in the answer array is not the answer array, but rather the value of temp. Effectively the following statement:
answer[row][column] = temp
Is trying to pass a single bool value as a 2-dimensional array, which won't work. In order to correctly call the method again you'll need to do your assignation of temp to the answer array, then call the function again.
answer[row][column] = temp;
FindSolution<_rows,_columns>(0, column + 1, answer);
Should work fine. (Note the explicit template arguments here <_rows,_columns>, this is only needed if you're using the function signature I posted above which made use of templates)

Multi-Dimensional Arrays--> Null Object Pointers

I am trying to develop a C++ application. Part of the Application is meant to create and initiate some properties of an Object and then store the object in a multi-dimensional array. Problem is after Object creation and storing the objects in the array, retrieving the Object values gives me pointers to NULL.
Please see code below for exact implementation:
Cell** TestMain::convertToMatrix(){
//char[] lengthArr = arra[0];
//int[][] temp
int rowCount = getCurrentRowCount(); // Gives the row count of the multi-dimensional array
int colCount = getCurrentColCount(); // Gives the column count of the multi-dimensional array
Cell** cellList;
cellList = new Cell*[rowCount];
for (int rowIter=rowCount-1;rowIter>=0; rowIter-- ){
cellList[rowIter] = new Cell[colCount];
for (int colIter=colCount-1;colIter>=0;colIter--) {
Cell *currentCell = new Cell(arra[rowIter][colIter],rowIter,colIter);
//Calculate weights
if (0==currentCell->getValue()) currentCell->setWeight(0);
if (1== currentCell->getValue()) {
if (isEdge(rowIter,colIter)) {
currentCell->setWeight(1);
}
else {
//currentCell->setWeight(1 + getMinimumValue(cellList[rowIter+1][colIter]->getWeight(),cellList[rowIter+1][colIter+1]->getWeight(),cellList[rowIter][colIter+1]->getWeight() ) );
currentCell->setWeight(1 + getMinimumValue(cellList[rowIter+1][colIter].getWeight(),cellList[rowIter+1][colIter+1].getWeight(),cellList[rowIter][colIter+1].getWeight() ) );
}
}
cellList[rowIter][colIter] = *currentCell;
}
}
return cellList;
}
`
Here is the code that performs the checking later in the code:
void StrawberryMain::printField(Cell** arrayOfCells) {
int row=0;
int column=0;
int maxRowCount= getCurrentRowCount();
int maxColCount = getCurrentColCount();
for (;row<maxRowCount;row++) {
Cell *cellArr = arrayOfCells[row];
for (;column<maxColCount;column++) {
Cell currentArrayCell = cellArr[column];
/*if (currentArrayCell==NULL){ // This line throws an error ->No match for ‘operator==’ in ‘currentArrayCell == 0’. Why?
printf("Returned Pointer for Cell was NULL");
}
else { */
printf("%s(%s)|", currentArrayCell.getWeight(),currentArrayCell.getValue());
/
//}
printf("\n");
}
}
When I run the program I get a whole load of nulls printed on my screen as output.( One null for every object supposed stored in the array
I come from a Java background ( although I have dabbled in QT C++ before) so I am a bit miffed why this is happening. As much as I would appreciate an answer I would value an explanation as to why this happens ( or a link which explains why this happens) as I really want to understand the workings of the Language.
Thanks in anticipation.
There are several issues in your code.
As already stated in comments, you have a memory leak issue.
if (currentArrayCell==NULL){ // This line throws an error ->No match for ‘operator==’ in ‘currentArrayCell == 0’. Why?
currentArrayCell as declared in your code is a Cell object. Not a pointer to one. So you aren't comparing if a pointed to Cell is NULL. That line is trying to compare if a Cell == 0. And since you apparently haven't defined an equality operator that could work with a Cell and 0 the compiler raises that error.
With that in mind, you should note that the line Cell currentArrayCell = cellArr[column];
is actually creating a copy of a Cell. It may not be important this time. But if you write similar code where you would modify currentArrayCell, then you would find that any changes are only made to the local copy and not to the element in cellArr.
This line:
printf("%s(%s)|", currentArrayCell.getWeight(),currentArrayCell.getValue());
is most likely not doing what you wanted. s% means you must pass a string (meaning something like a const char*). However, based on your other code I'm guessing that those member functions are returning integers. printf is a low level tool and does not have the ability to convert between data types in that manner. You either need to use the appropriate format specifier for the data type (such as %d for int) or convert the values before passing them to printf.
So what happens when you use the wrong format specifier is that printf tries to byte-wise interpret whatever you actually passed as whatever type the format specifier implies. In your case, it's trying to interpret integers as character pointers. I'm actually surprised this isn't causing a crash instead of just printing nulls.
just to give you an idea
template<typename T>
struct array {
array(int m, int n) {
size_[0] = m, size_[1] = n;
data_.resize(m*n);
}
T* operator[](int i) {
return &data_.front() + i*size_[1];
}
private:
stdvector<T> data_;
size_t size_[2];
};
It seems clear from your code that you're a C guy doing C++, so here are some classes that should be aware of in light of your goals.
Boost's ublas has a matrix implementation that would be a generally superior alternative to creating your own implementation.
Baring that, at bare minimum you should probably be working with vectors instead of dynamically created arrays to reduce the potential for memory leaks.

Difference dynamic static 2d array c++

Im using opensource library called wxFreeChart to draw some XY charts. In example there is code which uses static array as a serie :
double data1[][2] = {
{ 10, 20, },
{ 13, 16, },
{ 7, 30, },
{ 15, 34, },
{ 25, 4, },
};
dataset->AddSerie((double *) data1, WXSIZEOF(dynamicArray));
WXSIZEOF ismacro defined like: sizeof(array)/sizeof(array[0])
In this case everything works great but in my program Im using dynamic arrays (according to users input).
I made a test and wrotecode like below:
double **dynamicArray = NULL;
dynamicArray = new double *[5] ;
for( int i = 0 ; i < 5 ; i++ )
dynamicArray[i] = new double[2];
dynamicArray [0][0] = 10;
dynamicArray [0][1] = 20;
dynamicArray [1][0] = 13;
dynamicArray [1][1] = 16;
dynamicArray [2][0] = 7;
dynamicArray [2][1] = 30;
dynamicArray [3][0] = 15;
dynamicArray [3][1] = 34;
dynamicArray [4][0] = 25;
dynamicArray [4][1] = 4;
dataset->AddSerie((double *) *dynamicArray, WXSIZEOF(dynamicArray));
But it doesnt work correctly. I mean point arent drawn. I wonder if there is any possibility that I can "cheat" that method and give it dynamic array in way it understands it and will read data from correct place
thanks for help
You can't use the WXSIZEOF macro on dynamically allocated arrays. That's for determining the size of an array, you have a pointer to an array :) You can't use that trick with non-compile-time constant arrays.
The parameter wants the number of pairs in the array - and uses a tricky macro to figure it out (using the macro is better for maintainability - there's only one place that uses the size constant).
You can probably simply pass 5 to the function (or whatever variable you use to determine the size of your array).
(I should add that I'm not familiar with this particular API... and it could be doing something funky that would make this not work... but I doubt it)
EDIT. It appears (from some comments) that this function does require contiguous storage.
I don't think you need to write your own function to put these elements contiguous in memory. That would be a lot of reallocation and copying. More likely, you should be using a different class. After browsing their very minimal documentation, it looks like you can use XYDynamicSerie to build a dynamic list of points, then adding it to an XYDynamicDataset or something.
If You define an array like
double myArr[5][2];
All cells occupy a continuous chunk of memory and I'm pretty sure dataset->AddSerie relies on that.
You can't guarantee that if you allocate memory in chunks, using consecutive calls to new.
My proposition is to write a simple class that allocates a continuous chunk of memory for storage and uses operator() to access that memory as a two dimensional array using 2 indices. Internally You can use a vector<double> to manage the storage, and You can pass the address of the first element of that vector to dataset->AddSerie
Please check the code in this C++ FAQ example and try to understand it. The matrix example uses new[] and delete[]. You should use a vector instead, and the type double instead of Fred
Where in the example, there is a private section like this
class Matrix {
public:
...
private:
unsigned nrows_, ncols_;
Fred* data_;
};
(The example shows a matrix of Freds) You should use a vector<double>
class Matrix {
public:
...
private:
unsigned nrows_, ncols_;
vector<double> data_;
};
That will make the code much simpler. You don't even need a destructor, because the vector manages the memory.
Using #Stephen's answer I created xy plot which can easyly process various data without messing with convertion to (double *) and SIZE<...> macro. Maybe this chunk of code will be interesting for someone.
...
// create plot
XYPlot *plot = new XYPlot();
// create dynamic dataset and serie
XYDynamicDataset *ddataset = new XYDynamicDataset();
XYDynamicSerie *dds = new XYDynamicSerie();
///add values. you can simply grab this data from other sources
/// such as std::vector filled by user
dds->AddXY(1.1, 1.1);
dds->AddXY(3.1, 2.1);
dds->AddXY(5.1, 1.8);
ddataset->AddSerie(dds);
ddataset->SetRenderer(new XYLineRenderer());
plot->AddDataset(ddataset);
...