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.
Related
I have a class that contains a pointer. I want to keep the user of the class from accessing the address of the pointer (so they can't set it to another address, delete it, or what-not). However, I would like the user to be able to modify the pointer data (or member data if it's not POD) as well as call the pointer's methods (assuming it has any).
Is there any way of returning a pointer or reference that allows you to change the data that a pointer points to without being able to change the pointer value itself?
So:
class A
{
public:
int Value;
void Method();
};
class Wrapper
{
public:
Wrapper()
{
Pointer = new A;
}
// Method that somehow would give access to the object without
// Allowing the caller to access the actual address
A* GetPointer()
{
return Pointer;
}
private:
A* Pointer;
};
int main()
{
Wrapper foo;
foo.GetPointer()->Value = 12; // Allowed
foo.GetPointer()->Method(); // Allowed
A* ptr = foo.GetPointer(); // NOT Allowed
delete foo.GetPointer(); // NOT Allowed
return 0;
}
I realize I could modify member data with getters and setters, but I'm not sure what to do about the methods (pass a method pointer maybe?) and I'd like to know if there is a better way before I accept a solution that I personally think looks messy.
It's not possible. The whole reason why ->Value is legal is because the expression to the left is a (smart) pointer to A*.
Obviously, with a non-smart pointer you already have your A* right there. Since raw pointers are not user-defined types, you cannot mess with the overload resolution.
With a smart pointer, (*ptr).Value has to work. That means you have to return a A& from operator* which in turn means that &(*ptr) gets you the traw pointer from a smart pointer.
There's even std::addressof for classes that try to block operator&.
You could make a getter That returns a reference to the object, ex:
A &GetObject()
{
return *Pointer;
}
This allows full access to the pointed-to object without providing access to the pointer itself at all.
I was wondering when we use Pointer to Pointer in C++ and why we need to point to a pointer? I know that when we point to a pointer it means we are saving the memory address of a variable into the memory but I don't know why we need it? Also I have seen some examples that always the use Pointer-to-pointer in creating a Matrix! But why a Matrix may need Pointer to Pointer?
When to use Pointer-to-Pointer in C++?
I'd say it is better to never use it in C++. Ideally, you will only have to use it when dealing with C APIs or some legacy stuff, still related to or designed with C APIs in mind.
Pointer to pointer has pretty much been made obsolete by the C++ language features and the accompanying standard library. You have references for when you want to pass a pointer and edit the original pointer in a function, and for stuff like a pointer to an array of strings you are better off using a std::vector<std::string>. The same applies for multidimensional arrays, matrices and whatnot, C++ has a better way of dealing with those things than cryptic pointers to pointers.
When you want to change the value of variable passed to a function as the function argument, and preserve updated value outside of that function, you require pointer(single pointer) to that variable.
void modify(int* p)
{
*p = 10;
}
int main()
{
int a = 5;
modify(&a);
cout << a << endl;
}
Now when you want to change the value of the pointer passed to a function as the function argument, you require pointer to a pointer.
In simple words, Use ** when you want to preserve (OR retain change in) the Memory-Allocation or Assignment even outside of a function call. (So, Pass such function with double pointer arg.)
This may not be a very good example, but will show you the basic use:
void safe_free(int** p)
{
free(*p);
*p = 0;
}
int main()
{
int* p = (int*)malloc(sizeof(int));
cout << "p:" << p << endl;
*p = 42;
safe_free(&p);
cout << "p:" << p << endl;
}
We basically need pointer to pointer when we want to change the address of the pointer it is pointing to. very good example will be the case of linked list where we send a pointer to pointer to the head node when we try to insert a value to the beginning. Snippet of code pasted below.
int main()
{
/* Start with the empty list */
struct node* head = NULL;
/* Use push() to construct below list
1->2->1->3->1 */
push(&head, 1);
push(&head, 2);
.....
....
}
/* Given a reference (pointer to pointer) to the head
of a list and an int, push a new node on the front
of the list. */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
.....
.....
}
This is basically because, say a pointer was initially pointing to a memory location 0X100 and we want to change it to point it to some other location say 0X108. In such case pointer to pointer is passed.
You have probably seen int main() before, have you seen this:
int main(int argc, char** argv)
argv is indeed a double pointer, it's not actually a double pointer but it is a pointer to an array of pointers, each pointing to an array of characters pertaining to the command line arguments.
This is not the best example, as you probably want a more practical example. I will write up a better example and edit my post :)
Edit:
If you are familiar with classes and virtual functions then you may also be aware that any class who has a virtual function is automatically given a _vftp member variable.
The _vftp member is a pointer to a list of all the function pointers to your virtual functions. It is inserted at the very beginning of the structure.
If you created a new object as follows:
class myclass
{
public:
//void *_vftp; this is where the _vftp member gets inserted automatically
virtual void vfunc1();
};
void myclass::vfunc1() {printf("yay");}
void main() {
myclass *pMyObject = new myclass();
}
Upon instantiating myclass, the _vftp is added to the object structure and it is the very first variable. Because pMyObject is a pointer to this structure in memory, *pMyObject is eqal to _vftp.
Because _vftp is a pointer to the array of virtual function pointers, *_vftp is equal to vfunc1 (a function pointer).
This means if we dereference pMyObject twice, and call it, we will call vfunc1():
typedef (void* (__thiscall* fnVFunc1))(void);
((fnVFunc)**pMyObject)();
Although this is not a real use for double pointers this is a prime example of applying them. The most common place for double pointers lays in hacking and reverse engineering, where you commonly need to find a pointer in memory and alter whatever it points to.
Anytime you're dealing with C libraries. There are two common answers for the same question in C :
First, anytime you want doubly subscripted array, like :
int main(int argc, char** argv)
Second, anytime you want another return value from a function. There are many functions in libgit2 that do this because they wish to return a meaningful error type as opposed to just null, like the first argument in git_branch_create for example.
You could return a two item struct of course, but that's usually two extra lines of code. In fact, the pointer-to-pointer lets you write the pointer directly into a struct where it'll live.
In C++, you'd avoid using pointers directly whenever suitable C++ data types exist, and my libgit2 example is subsumed by C++'s exceptions, but..
You cannot call C++ from most high level languages, so if you're writing a library that you want available in say Perl, Python, and C++, then you write it in C.
Say you wanna instantiate an object in C++...
MyClass * obj = new MyClass();
You have to do this because new returns a pointer to the allocated object in dynamic memory. The following would be wrong:
MyClass obj = new MyClass(); // wrong. 'new' returns a pointer.
Say you want an array of objects...
MyClass ** objArray = new MyClass*[10];
The code below:
#include <iostream>
#include <list>
class A
{
public:
void printHello(){std::cout << "hello";}
};
int main(int argc, char *argv)
{
std::list<A*> lista;
lista.push_back(new A());
for(std::list<A*>::iterator it=lista.begin();it!=lista.end();++it)
{
//how to get to printHello method?
//it doesn't work
it->printHello();
}
return 0;
}
This code doesn't work. My question is how to get to method 'printHello' by iterator it? Thanks.
You want
(*it)->printHello();
as the *it returns the stored pointer A* and only then you can apply ->.
Just change following line
it->printHello();
to
(*it)->printHello();
The operator*() gives access to the contained data of the container, which in your case is a pointer. When not using pointers in containers, just using operator->() would work, too.
De-referencing it will give you pointer to A, then you need to access the methods or data members.
So use :
(*it)->printHello();
Let me expand on Daniel's answer.
When you stick an asterisk in front of a variable, it is called 'dereferencing'. Used this way, the Asterisk is a 'Dereference Operator'. To put it noob-ishly (I don't know what level of understanding you have offhand), *pMyPointer acts like it was the Object that the pMyPointer was pointing to. If it was a Pointer to a Pointer, then the result is just the Pointer.
As an example, when you call a method on a pointer, you use the Into Operator ->.
These two often do the same thing:
pMyPointer->MyFunction();
(*pMyPointer).MyFunction();
In the case of the C++ iterators, the Dereference Operator is overwritten to return the object stored in its position. In this case, what is stored in its position is a pointer, so you still have to use -> unless you stick another Dereference Operator in there.
I have some confusion about the shared_ptr copy constructor. Please consider the following 2 lines:
It is a "constant" reference to a shared_ptr object, that is passed to the copy constructor so that another shared_ptr object is initialized.
The copy constructor is supposed to also increment a member data - "reference counter" - which is also shared among all shared_ptr objects, due to the fact that it is a reference/pointer to some integer telling each shared_ptr object how many of them are still alive.
But, if the copy constructor attempts to increment the reference counting member data, does it not "hit" the const-ness of the shared_ptr passed by reference? Or, does the copy constructor internally use the const_cast operator to temporarily remove the const-ness of the argument?
The phenomenon you're experiencing is not special to the shared pointer. Here's a typical primeval example:
struct Foo
{
int * p;
Foo() : p(new int(1)) { }
};
void f(Foo const & x) // <-- const...?!?
{
*x.p = 12; // ...but this is fine!
}
It is true that x.p has type int * const inside f, but it is not an int const * const! In other words, you cannot change x.p, but you can change *x.p.
This is essentially what's going on in the shared pointer copy constructor (where *p takes the role of the reference counter).
Although the other answers are correct, it may not be immediately apparent how they apply. What we have is something like this:
template <class T>
struct shared_ptr_internal {
T *data;
size_t refs;
};
template <class T>
class shared_ptr {
shared_ptr_internal<T> *ptr;
public:
shared_ptr(shared_ptr const &p) {
ptr = p->ptr;
++(ptr->refs);
}
// ...
};
The important point here is that the shared_ptr just contains a pointer to the structure that contains the reference count. The fact that the shared_ptr itself is const doesn't affect the object it points at (what I've called shared_ptr_internal). As such, even when/if the shared_ptr itself is const, manipulating the reference count isn't a problem (and doesn't require a const_cast or mutable either).
I should probably add that in reality, you'd probably structure the code a bit differently than this -- in particular, you'd normally put more (all?) of the code to manipulate the reference count into the shared_ptr_internal (or whatever you decide to call it) itself, instead of messing with those in the parent shared_ptr class.
You'll also typically support weak_ptrs. To do this, you have a second reference count for the number of weak_ptrs that point to the same shared_ptr_internal object. You destroy the final pointee object when the shared_ptr reference count goes to 0, but only destroy the shared_ptr_internal object when both the shared_ptr and weak_ptr reference counts go to 0.
It uses an internal pointer which doesn't inherit the contests of the argument, like:
(*const_ref.member)++;
Is valid.
the pointer is constant, but not the value pointed to.
Wow, what an eye opener this has all been! Thanks to everyone that I have been able to pin down the source of confusion to the fact that I always assumed the following ("a" contains the address of "b") were all equivalent.
int const *a = &b; // option1
const int *a = &b; // option2
int * const a = &b; // option3
But I was wrong! Only the first two options are equivalent. The third is totally different.
With option1 or option2, "a" can point to anything it wants but cannot change the contents of what it points to.
With option3, once decided what "a" points to, it cannot point to anything else. But it is free to change the contents of what it is pointing to. So, it makes sense that shared_ptr uses option3.
I use boost shared_ptr to wrap a pointer. However I can only get the correct value in test_shared_ptr(), while in main(), I get the wrong value.
Expected output:
100
100
Actual output:
100
-572662307
It seems that the pointer becomes invalid in that case. Any correct approach to do the job? Thanks in advance.
Below is the source code.
#include <memory>
#include <iostream>
class TestClass
{
public:
TestClass(int &i);
void print_i();
private:
int *_i;
};
TestClass::TestClass(int &i) : _i(&i)
{
}
void TestClass::print_i()
{
std::cout << *_i << std::endl;
}
void print_i(int &i)
{
std::cout << i << std::endl;
}
TestClass *test_shared_ptr()
{
std::tr1::shared_ptr<int> i(new int());
*i = 100;
print_i(*i);
return new TestClass(*i);
}
int main(int argc, char** argv)
{
TestClass *p = test_shared_ptr();
p->print_i();
return 0;
}
You need to pass around the shared pointer, rather than references and pointers directly to the int.
What's happening is the shared pointer is never passed anywhere outside the test_shared_ptr() function. When that function returns, the shared pointer is destroyed. When it sees that nothing else has a reference to it's memory, it destroys the memory it was pointing at.
Basically, where you are using int &i and int *i change both to use std::tr1::shared_ptr<int> i.
You probably need to read up on shared pointer a bit more. Basically, they keep a reference count for the pointer they are pointing to. When they are copied, they up the reference count, and when they are destroyed the decrement it. When the reference count reaches 0 (nothing else is referencing the memory it is pointing at) it frees that memory. So, even though something is using that pointer in your case, because it did not use a shared pointer there is no way for the shared pointer to know that the memory is still being used, so it frees it.
It seems that the pointer becomes invalid in that case
Of course it becomes invalid. shared_ptr gets deleted when you leave test_shared_ptr, and i does not exist after that.
Any correct approach to do the job?
1) simply copy value of i. (use int i instead of int* i in TestClass). int is small, you won't lose anything.
or
2) use std::tr1::shared_ptr<int> instead of int* in TestClass.
The issue you are having is with your API contract.
I don't want to use shared pointer to pass variable values in TestClass's constructor, since I don't want to force the api user to use smart pointer
Your TestClass contract is currently looking like you want the caller to maintain the int item so that it has a lifetime longer than TestClass.
Your test case doesn't follow this contract rule however.
Actually I want to pass object by reference instead of generic type in my application.
Passing by reference or by pointer does not have anything to do with 'generic' type.
Here is a possible fix for your code testing your API, the scope of your int is then longer then sufficiently long (untill the end of the app) to handle all usages within TestClass
TestClass *test_shared_ptr(int &i)
{
i = 100;
print_i(i);
return new TestClass(i);
}
int main(int argc, char** argv)
{
std::tr1::shared_ptr<int> i(new int());
TestClass *p = test_shared_ptr(*i);
p->print_i();
return 0;
}
What you are doing really breaks the point of shared_ptr. Basically when you pass it out of that function is it magically supposed to break and, thus, not free the pointed too memory?
No. It frees it. Are you expecting the shared_ptr to still exist outside of the function so that when "p" drops out of scope it manages to call teh shared_ptr destructor? This can't happen. p is a pointer not a shared_ptr class.
Either return a shared_ptr or return the new'd pointer and delete it yourself.