Pointer dereference causes error when using arrow operator - c++

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

Related

I cant get my destructor to work in my code

Like i said in the title i cant get the destructor to work. The reason being is that in this program i am required to use a int* array with negative indices: I keep getting this error at random times while running also: Microsoft C++ exception: std::bad_alloc at memory location 0x009DF130.
heres the code that i believe involves the error:
private: int* run;
IntArray::IntArray(int a, int b)
{
int c = b-a;
run = new int [c] + a; //This is how i give it a negative indicie
h = b;
l = a;
}
IntArray::~IntArray()
{
delete[]run;
}
string IntArray::setName(string sp)
{
s = sp;
return s;
}
void runSim() {
IntArray b(-4, 6);
for (int i = b.low(); i <= b.high(); i++)
// low is the lowes bound high is the highest
b[i] = i * 10;
b.setName("b"); //this is where it breaks and gives me that error
wait();
}
The only right way to do this is to define a custom operator[] on your class. The code you have has numerous errors:
You access both low and high, that's high-low+1 elements. But you only allocate high-low.
If p=new int[high-low+1], then run=p+low; and run[low] means *(p + low + low). This is the proximate cause of your crash -- you wrote way outside the array, trashing internal metadata, which made dynamic allocation fail for the next user, your string's assignment operator.
You should have subtracted low when computing run, so that run[low] would give p[0], the first allocated element. But this might calculate a pointer outside the array (when low is positive), which is undefined behavior.
You pass a pointer to delete[] that didn't come from array new. You need to pass p, not run, to delete[].
You have no attempt at exception safety. Management of dynamic memory in C++ is an advanced topic, and the evidence shows that you are not ready to do it yet. So use an existing smart pointer to manage your memory.
Here's a better version:
#include <memory>
template<typename T>
class ArbBoundArray
{
int low;
std::unique_ptr<T[]> base;
public:
ArbBoundArray(int l, int h) : low(l), base(new T[h-l+1]) {}
T& operator[](int o) { return base[o-low]; }
const T& operator[](int o) const { return base[o-low]; }
};
That's it. Less code, works for any type not just int, and exception-safe.
You can add your special needs like a name or whatever on top of that basic concept.
Your have a simple errors:
Do not pass a value to delete [] you didn't get from new [] (or already passed once).
You need to undo your pointer-arithmetic to get the right pointer.
Also, be aware that if you create a pointer which points outside the array using pointer-arithmetic, you have Undefined Behavior.
If that's not your actual code, beware of trying to allocate less than 1 element.
Since you add a (aka l) to run when you new it, you must subtract when you delete it:
delete[] (run - l);
Not trying to be mean, but this is pretty bad code.
First of all, if b - a returns a number less than 0 you will probably get an std::bad_alloc and if a > c you will be stepping into undefined behaviour [scary] territory and will probably get a segfault if you try to use the pointer.
Seeing as though you try to delete[] the pointer that points to new int[c] + a you almost certainly will get a segfault.
You need to do run -= a before trying to delete[] it, the implementation will either store information about any new or malloc in the space before the pointer that you get given so that when you delete or free the memory it just has to run behind the pointer and get any information it needs or store the info in a hidden array somewhere that is indexed by the numerical representation of the pointer. But probably the first. Either way, you're screwed doing what you're doing.

C++ referencing an array of structs

I'm new to using C++ for complicated programming. I've been sifting through some leftover, uncommented, academic code handed down through my department, and I've stumbled across something I have no real idea how to google for. I don't understand the syntax in referencing an array of structs.
Here is a trimmed version of what I'm struggling with:
typedef struct
{
double x0,y0;
double r;
} circle;
double foo()
{
int N = 3;
double mtt;
circle circles[N];
for (int i = 0; i < N; i++)
{
mtt += mtt_call_func((circles+i), N);
}
return mtt;
}
What does (circles+i) mean in this case?
EDIT: the function should have (circles + i), not (circle + i).
circles+i is equivalent to &circles[i]. That's how pointer arithmetic works in C++.
Why is there a pointer? Well, when you give the name of an array, in a context other than &circles or sizeof circles, a temporary pointer is created that points to the first member of the array; that's what your code works with. Arrays are second-class citizens in C++; they don't behave like objects.
(I'm assuming your circle+i was a typo for circles+i as the others suggested)
circle+i means "take a pointer circle and move it i times by the size of the object pointed to by it". Pointer is involved because the name of the array is a pointer to it's first element.
Apart from this you should initialize an integer counter variable that is used in loop:
for (int i = 0; i < N; i++)
^^^^
{
mtt += mtt_call_func( ( circles + i), N);
^ // typo
}
In C, as in C++, it is legal to treat an array as a pointer. So circles+i adds i times the size of circle to the address of circles.
It might be clearer to write &circles[i]; in this form, it is more obvious that the expression produces a pointer to the ith struct in the array.
Each vector you declare in stack it's actually a pointer to the first index, 0, of the vector. Using i you move from index to index. As result, (circles+i) it's the equivalent of &circles[i].
& means the address of the variable. As in your function call, you send a pointer which stores an address of a variable, therefore & is required in front of circles[i] if you were to change to that, as you need the address of the i index of the vector circles to run your function.
For more about pointers, vectors and structures check this out: http://pw1.netcom.com/~tjensen/ptr/pointers.htm
It should cover you through ground basics.

Passing by reference 3-Dim Fixed length array

Can anyone hint on how to pass by reference an array of the kind
int array[2][3][4];
so that I may save his pointer in order to use and modify the array?
Like, if I were speaking about a single integer:
// Scope 1
int a = 3;
increment(&a);
// End Scope 1
// Scope 2
int *pa;
void increment(int *tpa) {
pa = tpa; *pa++;
}
// End Scope 2
Thanks a lot and best regards.
If you really want to pass the array by reference, you can do so:
void f(int (&a)[2][3][4]) { }
In C, which doesn't have references, you can pass the array by pointer (this works in C++ too, of course):
void f(int (*a)[2][3][4]) { }
C++:
void f(int (&array)[2][3][4])
{
}
C: There are no references in C
Note that no matter how you pass the array, via reference or not, the array is not going to be copied, so you'll get the original pointer. You can pass this array also like this:
void f(int array[][3][4])
{
}
Thanks to everyone who participated in this! sskuce provided a very good solution, taking advantage of a "container". I had thought about this but didn't really like the extra stuff.
I realized after a little jumbling that James McNellis had given the answer all along. So... here's the solution I prefer with no containers and no indexes arithmetic (mind the parenthesis):
void Scope1()
{
int array[2][3][4];
Scope2(&array);
}
int (*pArray)[2][3][4];
void Scope2(int (*tpArray)[2][3][4]))
{
pArray = tpArray;
(*pArray)[0][0][0] = 3;
}
Thanks again to everyone.
Edit: I'm keeping my original answer below, as I believe it's necessary for folks to understand how arrays are actually passed to functions and how they're layed out in memory, but on further reflection I think there is a simple and correct way to get what you want done.
Encapsulate the array within a struct, e.g.
typedef struct ArrayHolderStruct{
int array[2][3][4];
} ArrayHolder
//...
//scope 1
ArrayHolder thingy;
thingy.array[0] = something;
//other initialization.
F( &thingy );
//...
//scope 2
ArrayHolder *pa;
void F ( ArrayHolder *p ){
pa = p;
p->array[0][1][2] = 42;
}
//Call F first to set pa.
void G(){
pa->array[0][1][2] = 6 * 9; // if pa = &thingy, thingy will be modified.
}
The struct will allow you to maintain layout information about the encapsulated array, and you don't have to worry about nasty index arithmetic.
-----OLD ANSWER-----
Passing a reference to an array is not useful, unless you want to change the size or layout of the array (which you can't do with statically sized arrays anyway). You'll get a reference (or pointer) to the elements of the array even if you pass the array by "value". That is to say, if you declare your function:
void f ( int a[2][3][4] ){
a[0][1][2] = 42;
}
and call it like f( array ) when f exits, array[0][2][2] will have been set to 42, even though you didn't pass a "reference" to array into the function.
If you want to save a pointer to the array for later use in a library function, etc, you could do something like:
//scope 2
int * pa;
void f ( int a[2][3][4] ){
pa = &a[0][0][0];
}
It gets tricky at this point - you have to know how pa is layed (laid?) out in memory. I think C has standardized on 'row major order', so the array should be layed out in memory like:
a[0][0][0] a[0][0][1] a[0][0][2] a[0][0][3] a[0][1][0] ... a[0][2][3] a[1][0][0] a[1][0][1]... a[1][2][3]
So, to get at an element at index [n][j][k], you have to do something like:
pa[n * 12 + j * 4 + k] = something;
Basically, multiply each index by the number of elements that can be referenced by an index of that order, e.g. each k index points to exactly one element given a fixed j and n index, each j index can point to 4 elements given a fixed n index, and each n index can point to one of 12 (because 12 = 3 * 4) elements.
Like I said, it's tricky. See the wikipedia articles on Array Data Structures and Row-major order to get a better understanding of how these things are layed out.

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.

whats an example usage of c++ pointers?

i'm self-teaching c++ and i get how pointers work. but the doc i'm using is quite literal and the examples don't really go into why or when pointers would be used. a couple of real world examples would help me retain the knowledge.
You use pointers when you want your objects to exist longer than the current stack. You can also use them to avoid copying objects into containers.
// TODO: Remember to call DeleteObjects() when you're done here!!
std::vector<MyObject*> Objects;
void Test()
{
MyObject *const pObject = new MyObject();
Objects.push_back(pObject);
}
void DeleteObjects()
{
std::vector<MyObject*>::iterator it = Objects.begin(), itEnd = Objects.end();
for (; it != itEnd; ++it)
{
delete *it;
}
Objects.clear();
}
This is not an easy question to give a short and easy answer to, and I'm sure there's plenty of resources out there talking about pointers. Basically, whenever you'd like to use indirection (which may be even recursively) you need pointers.
Say for example a binary tree data structure, where each node have pointers to it's left and right sub trees, where either might a pointing to 0 (or NULL, meaning invalid pointer) to signify there's no sub tree there. This structure might look like this (not very C++-y, but that's a different story)
struct TreeNode
{
TreeNode* left;
TreeNode* right;
}
You can't use anything BUT a pointer in this case, as it'd be an infinitely large structure.
Uploading multiple data from a function. The caller would supply addresses of memory locations to be overwritten by the function
Dynamic memory allocation. Allocators would return pointers to newly allocated objects.
Passing array arguments: pass address instead of copying, to save performance for constant data.
This is not really a C++ matter, rather it is a C matter. For the beginner level, I would love to recommend the book Understanding Pointers in C
A simple example use of pointers is in linked lists. More info on wikipedia.
Pointers are useful when you need a function to return more than one variable. As an example, consider you are shopping at a grocery store. Each product has a name and a price. The name would be a string and the price a double. If there were a function called "buy", and you wanted to return both the name and price of the item, you might want to use a pointer.
void print_values(int* iptr, int size)
{
int i;
for (i=0; i < size; i++)
{
printf("%d ", *(iptr++));
}
printf("\n");
}
int main()
{
int table[256];
memset(table, 0, sizeof(table));
print_values(table, sizeof(table)/sizeof(int));
}
Or like a array of functions (example):
#define ___FUNC_B { func_1, func_2, func3 }
void ( __closure __fastcall * __FUNC_B [__FUNC_MAX] )( TObject* ) = ___FUNC_B;
Usage objects by pointers is in many cases is better:
CClass *ptr = new CClass();
/* something */
delete ptr;
If you have many objects and you must for example get it in a some arrange (eg. sort) you can use pointers for sort pointers to objects non objects:
vector <CClass*> Vptr;
for (i=0; i < 100; i++)
{
Vptr.push_back(new CClass());
}
sort(Vptr.begin(), Vptr.end(), __cmp_func);
/* something */
while (!Vptr.empty())
{
delete *(Vptr.begin());
Vptr.erase(Vptr.begin());
}
For dynamic memory alocation in C language:
char *memory = (char*) malloc(1024);
if (memory == NULL)
{
exit(1);
}
/* you have alocated 1KB in memory */
memory = (char*) realloc(2048);
if (memory == NULL)
{
exit(1);
}
/* you have alocated 2KB in memory */
free(memory);
/* you have nothing */
whats an example usage of c++
pointers?
Pointers address the following issues:
avoiding copying large chunks of memory around. That was in C at least, in C++ the preferred method is to use references. You can still use pointers if you want though.
allocating memory at runtime. This is needed when you have no idea at compilation how much memory you will use.
remembering the addresses of (member) functions for deferred calls (and callbacks).
allocating memory that outlasts it's current scope (it's still allocated after scope is finished).
sharing an object between multiple entities (multiple objects, multiple threads and so on). This means that you can pass the address of an object around and all entities using it will access the same data, not identical copies of it.
Sometimes pointers are also used as handles. That is, if you want to allow client code to uniquely identify a chunk of data without caring (or knowing) what the data is, you cast the address of the data (the pointer) to int/some other type and pass it around as a handle. This is commonly found in APIs that offer handles to client code but don't allow client code access to the real data (see use of WinAPI's HANDLE, HWND and so on - those are pointers in the internal implementation, but you don't know - or care - what the actual data is in order to use it).
Okay, I've seen so many terrible responses that I feel myself obligated to add yet another one.
First things first: we are talking C++ here. So many C uses are completely invalidated.
Terrible uses of pointers
You should learn RAII: this example is completely unsafe in the face of exception
// BAD
void func(size_t n)
{
int* array = new int[n];
// .. use array
delete[] array;
}
// GOOD
void func(size_t n)
{
std::vector<int> array(n, 0);
// .. use array
}
Rule of Thumb: if you see delete, you're doing it wrong. Chances are that if you see new too, though it's not as true because of argument forwarding issues.
Use references whenever possible
// BAD: Contract: do not pass NULL
void func(int* i);
// GOOD
void func(int& i);
Whenever the passing NULL does not make sense (and you don't need to rebind), use either a plain value or a (const) reference instead of a pointer.
Good uses of pointers:
Aliasing
void printSorted(std::vector<BigType> const& values)
{
std::vector<BigType*> references = from(values);
std::sort(references.begin(), references.end(), ByPointer());
std::transform(references.begin(), references.end(),
std::ostream_iterator<BigType>(std::cout, " "),
Dereference());
}
Optional Result
Object* find(Key const& key);
this is equivalent to:
boost::optional<Object&> find(Key const& key);
but quite less verbose.
Clone method
The use of a bare pointer as the return type of the clone method is mandated by the Boost Cloneable concept:
struct Base
{
virtual ~Base() {}
virtual Base* clone() const = 0;
};
There is a sound reason: taking advantage of covariant return types for the overloading of virtual methods. This allows us to write:
struct Derived: Base
{
virtual Derived* clone() const { return new Derived(*this); }
};
Thus taking full advantage, when cloning from a Derived const&, of the fact that we know that what is returned is at least a Derived.
It is up to the programmer to take care of the allocated memory unfortunately, so it must be used in conjunction with Smart Containers:
std::unique_ptr<Base> u = derived.clone();
A pointer can be considered a simple variable, but instead of saving a value it saves an adress to the position of the memory that stores a value.
Think the memory as a block of drawers and in each drawer you can put a value, to make it easier to find the values, you numerus the drawers. So, a position of memory would be a drawer and the block would be the full memory.
So, when you create a pointer, for example:
int* drawer = 0;
You are referring to the drawer which is labelled with the number 0 and contains an integer value, now you may think, ok, but, how can I get that value? Well, it's simple:
int value = *drawer;
By the same way you can store a new value on that drawer (memory address):
*drawer = 15;
Now comes the fun, the block of drawers is magic, and a drawer can take you to another drawer of the block, if we label them with the same number, the value that one stores is the same in the other:
int* drawer = 0;
int* drawer_copy = drawer;
*drawer = 15;
And what happens? That "drawer_copy", which is referring to the address 0 as "drawer" allows you to access to the integer value 15.
We can also save the address of a normal variable, we use the "&" prefix to get that adress:
int value = 15;
int* drawer = &value;
If we do this now:
value = 5;
"*drawer" will return a 5.
As you can see, pointers allow the user to have more control on the memory and to have reserved memory permanently, once you have declared a pointer you can preserve an address and access to it whenever you want. :)