My code:
#include<iostream>
using namespace std;
struct element
{
int liczba;
element *nastepny;
element();
};
element::element()
{
nastepny=0;
}
int main()
{
element pierwszy;
pierwszy.liczba=1;
element drugi;
(*nastepny).pierwszy=2;
drugi.liczba=2;
return 0;
}
It says that *nastepny was not declared, but I do not know how is it possible. I created structure with *nastepny. If I write element *nastepny, it says that element has no member named pierwszy. SOmething is going wrong because pierwszy is declared at the beginning of main function.
(*nastepny).pierwszy=2;
That makes no sense as nastepny is not declared statically or within its current or any parent scope. It is a member of your structure and only exists as a part of and instance of one.
Also, you cannot simply assign two to the address of some unallocated pointer. You have a pointer, but it does not yet point anywhere valid. So, either:
drugi.nastepny = malloc(sizeof *drugi.nastepny);
*drugi.nastepny = whatever;
To allocate space dynamically, or...
drugi.nastepny = &some_variable;
But watch for lifetime issues on that last one.
The error happens in
(*nastepny).pierwszy=2;
^^^^^^^^
nastepny is not declared in this scope. The member of the struct doesn't make it accessible outside the struct (instances).
I guess you are meaning something like this:
drugi.nastepny = &pierwszy;
drugi.nastepny->liczba = 2;
I auggest this:
pierwszy.nastepny = &drugi;
I'm not sure how you expect to get an object when you deference your pointer when you never assigned it a memory address?
If you want to get a pointer to the object itself then you can use the this pointer. However in this scenario such an application of it would make no sense.
The only assignment you provided to the element pointer was 0 (NULL), so it's not pointing to any element object.
Related
I have a struct, say:
struct Astruct {
int a;
int b;
}
And I have av instance of that struct say:
private:
Astruct My_List;
Then I have a function that I want to get the address of My_List.
public:
void Get_My_List(Astruct* List) {
List = &My_List;
}
However it seems to always set the argument Astruct* List = 0;
I know I probably could make a function called Astruct& Get_Address() or something but in this particular case I would like to know why I can't assign addresses in the argument. I mean it is possible to pass arguments as references and change the data. Or maybe I start to understand the problem now when I write this... Anyway just to be sure, is it possible to change the address the pointer points to via an argument? Or can I just change the data the pointer points to?
I figured it out. Yes it was about confusion, but not pointer confusion, more like argument confusion!
So the problem is that I thought I could "return" values via arguments. I thought that because I have previously created functions that takes a pointer and then the function changes the data the address points to. And yes it is "set" to zero. I mean #john is right, the code can't set it, but it is never changed. Because the value I pass in is initialized to zero and I can't change an argument, in this case Astruct* List. So the pointer I pass remains unchanged.
So what I had to do was to make the function take a pointer to a pointer.
void Get_My_List(Astruct** List) {
*List = &My_List;
}
And pass the address to the pointer instead. In that case I can change the data the pointer points to, which is a pointer.
Thanks, bye!
You can pass the reference-to-pointer:
void Get_My_List(Astruct*& List) {
List = &My_List;
}
and call it like that:
AstructHolder obj{};
Astruct* my_ptr{nullptr};
obj.Get_My_List(my_ptr);
I was wandering through the code of Sequitur G2P and found a really strange line of code:
public:
...
const Node *childrenEnd() const { return (this+1)->finalized.firstChild_; }
I know that this is a pointer to the current object, and since it is a pointer, the operation is perfectly legal, but what does this+1 actually refer to?
Presumably this is part of an array, so this+1 would refer to the next object in that array.
this is simply a pointer which refers to this object. Since it's a pointer, you can apply pointer arithmetic and even array indexing.
If this object is an element in an array, this+1 would point to the next object in the array.
If it's not, well it's just going to treat whatever is at that memory the same as this object, which will be undefined behaviour unless it is the same type.
As it is NLP it makes sense to optimize memory management. I assume you find overloaded new/delete methods as well.
The this+1 construct assumes all objects reside in an array. The name 'childrenEnd' of the method indicates it returns a pointer to an address of the end of the children of the current node.
Thus you are looking at an implementation of a tree structure. All siblings are adjacent and their children as well.
"this + 1" in C++ class means:
if the "this" object is a member of another object it will point to the address of the parent's object next variable declared just after the "this" object variable:
Example:
class B
{
public:
void* data()
{
return this + 1;
}
};
class A
{
public:
B m_b;
char m_test;
};
int main(int argc, char* argv[])
{
A a;
a.m_test = 'H';
void* p = a.m_b.data();
char c;
memcpy(&c, p, sizeof(char));
return 0;
}
c is equal 'H'.
Long story short it allows to access to parent's class data without passing parent's pointer to the child class. In this example this + 1 point to the m_test member of the class A.
Actually, there is a case, when this thing could be used. I don't recommend to use this method, but it certainly works.
I believe, in NLP code it was used something like that:
when you want your object to behave as a collection (an array etc) to use it similarly as an array with something range-based etc, you can do this trick:
struct Obj {
...
Obj* begin() { return this; }
Obj* end() { return this+1; }
...
}
Now, you can use this object in, for example, range-based for-loops...
Sometimes all that is necessary... but just even there you'd better use "nullptr" or even do refactoring than to use this trick.
Summarizing:
Is it possible to change a class member property memory address?
What lead me to do this question:
I'm not sure if what I want to do will lead into my expected behavior, and even if it works as expected, if it is what I should do.
So, I have a member property which I want to read from disk, say for instance that it is prop from MyClass. The routine I have that read the property from disk getVarOnFile I do not have access to the implementation, but it uses a pointer to the type to fill the value on the file.
In the documentation it says that if the property does not exists, the pointer may be null, although I am unsure if it will set it to null or it is because it expects that I enter null pointer to the function.
Because of that, instead of using the destVar pointer itself, I use a localVar pointer, and then set the destVar to localVar.
But I am not sure if I should do that, it seems that this will segment memory, where most of the members are close in the memory, but not this one that I set to the memory place reserved by the file.
void readHelper(const char* propOnFile, float*& destVar)
{
// check if propOnFile exists
float *localVar = nullptr;
getFileOnVar(propOnFile,localVar);
if ( localVar != nullptr){
destVar
}
}
class MyClass {
private:
float prop;
public:
static MyClass *read(const char* file){
readHelper("prop",&(this->prop));
}
};
I am not sure what would happen to the original memory place reserved for the original class property member, which was replaced to a new place. It will be freed or this would be memory leak?
Changing class member address
If I understand your question correctly, that is not possible.
Say you have:
struct Foo
{
int a;
};
Foo f;
Once you have created f, the address of f and f.a are not changeable. You can only modify their values.
I have a class with a static member that's a pointer like so :
animation.h
class Animation
{
public:
Animation();
static QString *m;
};
animation.cpp
#include "animation.h"
QString* Animation::m = 0;
Animation::Animation()
{
}
When I try to initialize that 'm' pointer from another class like so :
Animation::m = new QString("testing");
It works.
But when I do it this way :
QString x("Testing");
Animation::m = &x;
The program crashes.
What is wrong with this second method ?
Also I would like to have that static pointer as private so I can make static getter and setter functions to it. The setter should use the second method as the 'x' will come in a parameter so I'm stuck.
Thanks for any help!
I bet it's not crashing on that line, but afterwards.
The problem is that you're taking the address of a variable located in automatic memory, and probably try to access it afterwards. The variable x will be destroyed when it's scope ends, but Animation::m will still point to that memory (memory you no longer own after x went out of scope). This results in undefined behavior.
Just like the following would be illegal:
int* x = NULL;
{
int k = 3;
x = &k;
}
*x = 4;
Workaround assign to the value, not the pointer (provided it was previously assigned to a valid QString*):
QString x("Testing");
*(Animation::m) = x;
What is wrong with this second method ?
It crashes because you most likely access it beyond the scope in which x was created.
Automatic variables are automatically destroyed once the control exits the scope { } in which they were created, So beyond the scope what you have is an pointer pointing to data that does not exist. Accessing this data causes an Undefined Behavior and a crash.
How to go about it?
You should dynamically allocate memory and then copy the string to the dynamically allocated pointer so that you are able to access it everywhere. This way the string remains valid unless and untill explicitly deleteed.
I'll bet that your program crashes when you use Animation::m after x has been destroyed (probably by going out of scope).
If you want to use a setter to assign to Animation::m, you'll need to pass in the argument as a pointer or by reference:
class Animation
{
public:
Animation();
void set_m( QString* ptr) {
m = ptr;
}
void set_m( QString& ref) {
m = &ref;
}
private:
static QString *m;
};
However, you'll still need to make sure that whatever m points still is still alive when you try to use m.
This problem involved me not knowing enough of C++. I am trying to access a specific value that I had placed in the Heap, but I'm unsure of how to access it. In my problem, I had placed a value in a heap from a data member function in an object, and I am trying to access it in another data member function. Problem is I do not know how, and I had searched examples online, but none were what I needed as they were all in int main() and were not specifically what I needed.
In the first data member function, I declare the value I want to be sent to the Heap;
Here's an example of what my first data member function.
void Grid::HeapValues()
{
//Initializing Variable
value = 2; //The type is already declared
//Pointers point a type towards the Heap
int* pValue = new int;
//Initialize an a value of in the Heap
*pValue = value;
}
And in data member function This is what want:
void Grid::AccessHeap()
{
//Extracting heap:
int heap_value = *pValue; //*pValue does not exist in this function
cout << heap_value; //Delays the value 2, which is found
//in the first data member function
}
I feel foolish for asking, but I am unable to find the answers and do not how. Does anyone know how to access a value from the heap in a simple way? And I would need it to be able to access in more then two data member function.
pValue needs to be a member-variable of the class Grid.
class Grid
{
private: int* pValue;
public: void HeapValues();
void AccessHeap();
};
Now the member-variable pValue is accessible from any member-function of Grid.
Don't forget to delete your pointer in the destructor when you are done. For more information visit:
http://www.cplusplus.com/doc/tutorial/variables.html <-- Variable scope
http://www.cplusplus.com/doc/tutorial/pointers.html <-- Pointers
http://www.cplusplus.com/doc/tutorial/dynamic.html <-- Dynamic memory
Like Aaron said you can make the value a member of your Grid class. In this case though there is no need for it to be a pointer to an int.
class Grid
{
private:
int value;
public:
void HeapValue();
void AccessHeap();
};
The value will be stored as part of the object wherever it is instanciated. You can make it on the stack or the heap, it doesn't matter. For simple values like the built in types and Objects that will be owned by the instance of the class it is unnecessary to allocate them using new. This way you don't need to worry about cleaning up with the delete operator in the Grid destructor, just make sure you dispose of the owning Grid instance properly ;-)
Of coarse there are exceptions to this that you will learn as you delve more into C++, but for your example the above will be fine.
Why do you want it on the heap? If you add it as part of the class then it will be in the same place the class is, possibly on the stack or in global memory. Perhaps you want to have a variable size to your integer pointer? In that case, then you need to be sure to deallocate the memory when you are done with it.
The problem with stuff on the heap is finding it. There is no accessing it by name, unless you add a mechanism for that. Somehow you need to communicate the location to whatever code needs to access it. In this case, it looks like you only need access within the Grid class, so it is easy. Just make it a member variable like Aaron indicates. You might end up with something like:
class Grid
{
protected:
int* pVals;
public:
Grid() pVals(NULL) { }
~Grid() { delete [] pVals; }
void HeapValues() {
pVals = new int[getHeapValuesSize()];
pVals[0] = 1; // ...
}
void AccessHeap() {
cout << pVals[0]; // ...
}
(On a side note, you appear to be using the phrase "data member function" when you mean "member function". "Data member" refers to member data of a class, like pVals, but I'm not sure what "data member function" would mean.)