Multi-Dimensional Arrays--> Null Object Pointers - c++

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.

Related

Pointer dereference causes error when using arrow operator

I'm trying to use pointers (because I need them), but for some reason, I don't understand them. (The explanation is under the code snipped)
void Spiel::SetFigureToField(Figur *figur)
{
*figur->teampos = *figur->*spieler->GiveTeamPos();
figur->teampos = figur->spieler->GiveTeamPos();
figur->pos = figur->teampos;
this->spielfeld[figur->Startpoint].Figuren.push_back(figur);
std::vector<Figur*>* figs = &figur->spieler->SpawnField;
for (int i = 0; i < figs.size(); i++) //find figure in spawnfield and erase it
{
if (*figs[i] == figur)
{
*figs.erase(*figs.begin() + i);
}
}
}
struct Figur
{
Spieler* spieler{};
int Startpoint{}; //startpoint on spielfeld
int teampos{0}; //pos in Array | 0 best - 4 worst | 5 spawnfield
int pos{};
int id{};
void reset(int team, int pos)
{
if (team == 0) this->Startpoint = 0;
else this->Startpoint = 21;
teampos = pos;
}
};
class Spieler
{
public:
Spieler(std::string wuerfelS, int team);
//Stats
int Wins{ 0 };
int AnzahlWuerfen{ 0 };
//for game
int FigursActive{ 0 }; //keepstrack of the figurs on field
Wuerfel wuerfel{};
std::vector<Figur>figuren{};
std::vector<Figur*>SpawnField{};
Figur* ZielFeldArray[4];
int GiveTeamPos();
};
Okay, the first function is my problem point.
Explanation of how it should function: So a Figur (pointer) gets passed in the function and it should place to a gamefield.
What I understand: I want to edit the teampos in the figur. So what i learn is that I should dereference it (so I get the values from the memory address), but if i do *figur->teampos it just gives me an error.
The other one:
std::vector<Figur*>* figs = &figur->spieler->SpawnField;
With this I should get the pointer of the SpawnField vector. What I thought is that i have to dereference it to use the values and methods of vectors. *figs.size() This is what I tried and it gives an error.
It's clear that I don't understand pointers, but every tutorial says: if you have a pointer you have to dereference it to access the values (okay makes sense), but it doesn't function
I'm trying use pointers (because i need them), but for some reason i dont understand them.
How can you be so sure you need them if you don't understand them? I really mean this question, as many programmers, even good one, will be convinced that a solution is the best, but in reality a misunderstanding of the problem is at the core of the issue instead.
What i understand: I want to edit the teampos in the figur. So what i learn is that i should dereference it (so I get the values from the memory address), but if i do *figur->teampos it just gives me an error.
C++ has two dereferencing operators. The unary star *ptr and the arrow ptr->. If you use the arrow figur->teampos then you already deferencence figur here. ptr->member is semantically equivalent to (*ptr).member.
The other one: std::vector<Figur*>* figs = &figur->spieler->SpawnField; with this i should get the pointer of the SpawnField vector. What I thought is that i have to dereference it to use the values and methods of vectors. *figs.size() This is what i tried and it gives an error.
To access the vector's member, you should use the arrow: figs->size() as the star operator cannot access members directly.
Same thing when indexing. doing vec_ptr[1] will do the [] operator on the pointer, but should be on the vector itself. You will need (*vec_ptr)[1].

Creating a C++ array that can be several types

I have a function that returns a void*. Right now, when this function is completed, a UINT16* array is returned as the void*. The UINT16 array is created at the start of the method, but now I need a way to determine the type of array and create that type instead. For example, some data processing occurs and determines that an array of type int should be created, so an int array is created and returned. Other types like double and byte can also be created.
How do I go about achieving this?
My current code has
UINT16* data_out = new UINT16[arraySize];
I know I can create a large if/else or switch statement, but I'm wondering if there is a better way.
Something like that perhaps ?
This will not work, but thanks for the upvote. In fact it could work, but you'll have to know the type returned by Foo to be able to use it. But the type is determined inside Foo, that's a serious conception drawback. You should rethink the way you want this to work.
enum class ArrayType
{
Int,
Double
};
template <typename T>
T* CreateArray(size_t size)
{
T* t = new T[size];
return t;
}
void* Foo(param1, param2, etc..)
{
size_t size;
ArrayType type;
.. Do things to determine the type
switch(type)
{
case ArrayType::Int:
return CreateArray<int>(size);
case ArrayType::Double:
return CreateArray<double>(size);
default:
return 0;
}
return 0;
}
Uhm... sorry if this is more of a question than a comment... :| I can't comment rn.
If you want a core solution, you could create a linked list class that has different type outlets. Basically, instead of having just an UINT_64* next;, you would have:
int* nextInt;
double* nextDouble;
And so on and so forth. Then, if you want to tag a double along, you could just use the nextDouble outlet. To find which outlet to go to, just check if the int is pointing to anything; if not, go next. I know this seems like a REALLY annoying and bulky option, but I suppose it does the job.
I'm not sure why you have to use a practically untyped return value using void*, but let's suppose that there are reasons for it.
There are actually two issues, namely creating the array and using it then.
When creating an array of different types based on some logic, you somehow have to deal with if or switch(); how else would you express the logic determining the desired result type? But, if you like, you could also use something like result = malloc(nrOfItems*sizeOfItem), and determine sizeOfItem on any logic you like, even based on arithmetic calculations.
The more interesting or critical thing is how the caller shall use the result of the respective function, as accessing the elements of an array requires knowledge about the type or the size of the elements in it.
Suppose, for example, the following code:
void* getSomeItems() {
if (std::rand() > 100000)
return new char[200];
else
return new double[200];
}
int main() {
void* someItems = getSomeItems();
double c = ((double*)someItems)[199]; // Critical!
// how shall we know if element type is double?
// if rand() decided to create items of type char,
// this code accesses non allocated memory
...
So, unless your function can give back the information on which type has been created (and actually also the size of the array), the return value is almost needless.
I'd suggest not to use void* for this. If you know the type before calling the function, you could use templates, vectors, or other things. If you do not know type and/or size before calling, return a structure that - besides the allocated array - also provides type/size information.
BTW: do not forget to delete[] / free the result at the end.
Void * functions can be fun and do some very interesting things... (Sorry for linking a previous answer of mine, but it's the first example which came to me.) But they aren't safe, and have zero type checking...
So in your case, you only need a simple template function, and the auto keyword. Something like:
#include <iostream>
#include <iomanip>
template <typename T>
T * returnAnArray (int size) {
T * data_out = new T[size];
return data_out;
}
int main() {
int size = 3;
auto array = returnAnArray<double>(3);
for(int i=0;i<size;++i)
array[i] = 0;
for(int i=0;i<size;++i){
std::cout << std::setprecision(2);
std::cout << array[i] << std::endl;
}
delete [] array;
return 0;
}
I did have some fun, and did create a void * function:
template <typename T>
void * returnVoidPointerToArray(int size) {
return new T[size];
}
The function, when used, must be cast for it could return something:
auto chArray = (char*)returnVoidPointerToArray<char>(size);
But the output looks like:
5.00
5.00
5.00
ggg
ggg
ggg
Program ended with exit code: 0
Note how double are a single value, but the same function also initialized a 2d array of characters... Cool, right? Albeit, it's a dirtier, different way of templating functions.
And, like the commenter said, probably a good idea to use unique pointers. :)
And like the other commenter said, I cast the array to char* and got a char* array. :)

Why is the dynamically allocated array attribute of my class template only able to store one item?

I am trying to expand the functionality of a class template I created. Previously it allowed you to use key-value pairs of any type but only if you knew the size of the arrays at compile time. It looked like this:
template <typename K, typename V, int N>
class KVList {
size_t arraySize;
size_t numberOfElements;
K keys[N];
V values[N];
public:
KVList() : arraySize(N), numberOfElements(0) { }
// More member functions
}
I wanted to be able to use this for a dynamic number of elements decided at run-time, so I changed the code to this:
template <typename K, typename V>
class KVList {
size_t arraySize;
size_t numberOfElements;
K* keys;
V* values;
public:
KVList(size_t size) : numberOfElements(0) {
arraySize = size;
keys = new K[size];
values = new V[size];
}
~KVList() {
delete[] keys;
keys = nullptr;
delete[] values;
values = nullptr;
}
// More member functions
}
The new constructor has one parameter which is the size that will be used for the KVList. It still starts the numberOfElements at 0 because both of these uses would start the KVList empty, but it does set arraySize to the value of the size parameter. Then it dynamically allocated memory for the arrays of keys and values. An added destructor deallocates the memory for these arrays and then sets them to nullptr.
This compiles and runs, but it only stores the first key and first value I try to add to it. There is a member function in both that adds a key-value pair to the arrays. I tested this with the Visual Studio 2015 debugger and noticed it storing the first key-value pair fine, and then it attempts to store the next key-value pair in the next index, but the data goes no where. And the debugger only shows one slot in each array. When I attempt to cout the data I thought I stored at that second index, I get a very small number (float data type was trying to be stored), not the data I was trying to store.
I understand it might be worth using the vectors to accomplish this. However, this is an expansion on an assignment I completed in my C++ class in school and my goal with doing this was to try to get it done, and understand what might cause issues doing it this way, since this is the obvious way to me with the knowledge I have so far.
EDIT: Code used to add a key-value pair:
// Adds a new element to the list if room exists and returns a reference to the current object, does nothing if no room exists
KVList& add(const K& key, const V& value) {
if (numberOfElements < arraySize) {
keys[numberOfElements] = key;
values[numberOfElements] = value;
numberOfElements++;
}
return *this;
}
EDIT: Code that calls add():
// Temp strings for parts of a grade record
string studentNumber, grade;
// Get each part of the grade record
getline(fin, studentNumber, subGradeDelim); // subGradeDelim is a char whose value is ' '
getline(fin, grade, gradeDelim); // gradeDelim is a char whose value is '\n'
// Attempt to parse and store the data from the temp strings
try {
data.add(stoi(studentNumber), stof(grade)); // data is a KVList<size_t, float> attribute
}
catch (...) {
// Temporary safeguard, will implement throwing later
data.add(0u, -1);
}
Code used to test displaying the info:
void Grades::displayGrades(ostream& os) const {
// Just doing first two as test
os << data.value(0) << std::endl;
os << data.value(1);
}
Code in main cpp file used for testing:
Grades grades("w6.dat");
grades.displayGrades(cout);
Contents of w6.dat:
1022342 67.4
1024567 73.5
2031456 79.3
6032144 53.5
1053250 92.1
3026721 86.5
7420134 62.3
9762314 58.7
6521045 34.6
Output:
67.4
-1.9984e+18
The problem (or at least one of them) is with this line from your pastebin:
data = KVList<size_t, float>(records);
This seemingly innocent line is doing a lot. Because data already exists, being default constructed the instance that you entered the body of the Grades constructor, this will do three things:
It will construct a KVList on the right hand side, using its constructor.
It will call the copy assignment operator and assign what we constructed in step 1 to data.
The object on the right hand side gets destructed.
You may be thinking: what copy assignment operator, I never wrote one. Well, the compiler generates it for you automatically. Actually, in C++11, generating a copy assignment operator automatically with an explicit destructor (as you have) is deprecated; but it's still there.
The problem is that the compiler generated copy assignment operator does not work well for you. All your member variables are trivial types: integers and pointers. So they just copied over. This means that after step 2, the class has just been copied over in the most obvious way. That, in turn, means that for a brief instance, there is an object on the left and right, that both have pointers pointing to the same place in memory. When step 3 fires, the right hand object actually goes ahead and deletes the memory. So data is left with pointers pointing to random junk memory. Writing to this random memory is undefined behavior, so your program may do (not necessarily deterministic) strange things.
There are (to be honest) many issues with how your explicit resource managing class is written, too many to be covered here. I think that in Accelerated C+, a really excellent book, it will walk you through these issues, and there is an entire chapter covering every single detail of how to properly write such a class.

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)

C++ - is a pointer to a single value same as a size 1 dynamic array?

I have this snippet of code which I am considering to simplfy:
if (numberOfResults > 1)
{
trackResult_ = new TrackResult[numberOfResults];
for (int i=0; i < numberOfResults; i++)
{
// Make a deep copy
TrackResult tempResult = result[i];
TrackResult * clone = new TrackResult(tempResult);
trackResult_[i] = *clone;
}
storeJointResults(trackResult_, numberOfResults);
}
else
{
trackResult_ = new TrackResult(*result);
}
(I have 'no choice' but to use a simple dynamic array here. Vectors are deemed 'too complicated' at my workplace)
I am wondering if I can get away with
// even if we just have one result, we init an array size of one
trackResult_ = new TrackResult[numberOfResults];
However, I have in several points check for the number of results and act accordingly
if (numberOfResults_ == 1)
{
velocity = trackResult_.velocity;
}
Would those code still work? If not, why?
The array of size 1 does not need to be a special case.
When you allocate a dynamic array you are given a pointer to the first element. If the array is of size 1, this is pretty much indistinguishable from just having allocated a single instance of the object.
Your special case usage would work if you changed the . to an ->
However I'd recommend not special-casing it and just use trackResult_[0].velocity
No, you need to ensure you match the correct scalar delete or array delete[] depending on whether you say new TrackResult[n]; or new TrackResult;.
Also, this leaks memory for each loop iteration:
TrackResult tempResult = result[i];
TrackResult * clone = new TrackResult(tempResult);
TrackResult_[i] = *clone;
How are vectors too complicated? If anything, the simplify your code.
I agree with Alex, using the . operator on a pointer is not my recommended style either, so those other points ought to be changed anyhow, and thus not discourage you from simplifying the piece of code you mention.