C++ array initialized in function cannot be accessed in main - c++

I have a function used to initialize array in C++. after the initialization, main can not access the data in the array. Don't know why. Any help?
void testArray(int *listPtr)
{
listPtr=new int[2];
listPtr[0]=0;
listPtr[1]=1;
}// end testArray
void main()
{
int *list;
testArray(list);
cout<<list[0]<<list[1]<<endl; // this gives some random output
} // end main

This is because the pointer is passed by value. The argument to the function is copied, and the first line of your function replaces the local copy of the pointer with the result of the new expression. The original copy of your pointer, back in main(), is unaffected by this.
You can "fix" this by either passing the pointer by reference:
void testArray(int*& listPtr)
{
listPtr = new int[2];
// ...
}
int main()
{
int* list = 0;
testArray(list);
// ...
delete list;
return 0;
}
or by passing a pointer to the pointer:
void testArray(int** listPtr)
{
*listPtr = new int[2];
// ...
}
int main()
{
int* list = 0;
testArray(&list);
// ...
delete list;
return 0;
}
or, better still, by using a C++ standard library container that provides value semantics (in conjunction with a reference argument):
void testVec(std::vector<int>& list)
{
list.resize(2);
list[0] = 0;
list[1] = 1;
}
int main()
{
std::vector<int> list;
testVec(list);
// ...
return 0;
}
Analogy time:
The problem arises because a pointer is a separate entity (object) that points to some other object. Pointers can be copied just as regular objects can, and there is no special consideration given to them to make sure that the thing they point to is updated to reflect any change made to the pointer. A reference is a different beast entirely. Once a reference has been bound to some object, it is (to all intents and purposes) indistinguishable from the object itself; any operation on the reference is an operation on the underlying object. You can think of it as though you possess a cat named Fluffy, and you let your friend borrow Fluffy; but your friend calls her Buffy. It's the same cat, and if your friend trims her claws, the next time you see Fluffy, she'll have trimmed claws.
For the pointer example, you have Fluffy, and you give your friend a note with Fluffy's address written on it. Your friend goes and gets a new cat, and writes the new cat's address on top of the note you gave them. Now, when your friend trims the claws of the new cat, nothing at all happens to Fluffy. The note just allows your friend to go to the place where Fluffy lives; right up to the point where your friend overwrites the note with the address of some other cat.
References make it much easier to reason about the behaviour of your code, and should be preferred in almost all situations.

You need pass by reference, so that the change to the pointer listPtr itself can be passed out to the outter variable. Remember, you are changing the value of "the pointer itself", which is invisible to the caller if pass by value.
void testArray(int * &listPtr)
{
listPtr=new int[2];
listPtr[0]=0;
listPtr[1]=1;
}// end testArray

You need to use pass by reference, so that listPtr get updated while initializing it in testarray function.
To do that do the following -
void testArray(int * &listPtr)
{
listPtr=new int[2];
listPtr[0]=0;
listPtr[1]=1;
}
If you are confused about the above solution you can simply declare and initialize this one globally.

Related

What does the pointer 'this+1' refer to in C++?

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.

When to use Pointer-to-Pointer in C++?

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

function declaration or prototype. How do i define it?

I have been working on linked lists and trees recently. But i am not sure when to declare a function as:
preorder(struct node* root);
or
preorder(struct node** root);
when both work quite the same. To be more precise when do i have to design my function as double pointer and as a single pointer.
Thanks.
P.S: insertion of a node in linked list needs to have double pointer as in:
insert(struct node** root,int value);
unless the root node is defined as a global value. While the preorder works well with a single pointer. If anyone can explain with this as an example it would be highly helpful.
That depends on what preorder() does. If it prints some stuff without modifying the list/tree, you only need a single pointer. If there is a chance that the root will have to be replaced, you need a double pointer.
This is because arguments are passed by value in C. You cannot modify the original variable if a copy of it is passed to your function:
int inc(int x)
{
x = x + 1; // this will never work
}
To get around this, instead of passing in the argument you can pass in the address of that argument (a pointer to it). The function can then dereference the pointer and modify the value it points to.
// usage: inc(&x) where x is an int
int inc(int *ptr)
{
*ptr = *ptr + 1; // this will work
}
With your list/tree, you are already using pointers. This lets you access and modify the pointed-to object (e.g. get/set the next member of the root), but doesn't let you modify the pointer itself (e.g. replace the root with a different node). To do that, another level needs to be introduced, hence the pointer-to-pointer-to-node.
preorder(struct node** root);
Here you pass the address of root, because you may wish to update it withing the function.
preorder(struct node* root);
Here you simply use root to transverse the data structure, without modifying the root.
It's kind of confusing, but I will give it a shot and maybe my way of explaining will make sense to someone :)
Every variable in a function's scope is defined in a standard way, essentially.. (variable type) (variable name). Whether that's:
int foo; // an int called foo
or
char *bar; // a char * called bar
or
struct xyz *blah; // a struct xyz * called blah
and the way you treat foo, bar, and blah are the same when you pass them as arguments to another function. If you want the called function to just look at or use the variables, you can pass them as they are (by value) which creates a copy of the values (an int, or the address of a char, or the address of a struct xyz). So, if you change the value of the int, or the address of the struct xyz in the called function, it is only changed for that local copy of the original variable.
If you want the called function to actually change the value of the original variable (increment foo, malloc memory for bar, or change which element in a list blah points to for example) you need to tell the called function WHERE to make that change (pass them by reference) which results in the called function being declared as f(int *foo) or f(char **bar) or f(struct xyz **blah).
People get caught up on levels of indirection but all that really matters when you're calling another function is what your intentions are with respect to using or changing the variables in the local scope.
You pass a pointer instead when you want to change the thing being passed to the routine. Your confusion arises because the thing is also a pointer.
So if you want to pass a pointer to a routine, and you also want to (potentially) modify the pointer itself, use a double pointer.
If you want to pass a pointer to a routine but all you want to do is change or query what the pointer is pointing to use a single pointer.
That's the difference, do you want to change the pointer or do you want to access what the pointer is pointing to.
Since question is tagged both C and C++, here is a look at the difference from that perspective. This answer does not touch C++ container classes or smart pointers, which should usually be preferred in C++ code. Below are 4 cases, two which can modify caller's struct and caller's pointer, and two which can only modify contents of given struct.
C++ modify pointer
When you want the function to modify a pointer, and have the pointer values returned to the caller in C++, you would do this using a reference to pointer:
void clearNode(struct node *&n){
n->field = 0; // modify caller's struct
n = nullptr; // set caller's pointer to NULL (C++11)
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // OK, np becomes null, n.field becomes 0
clearNode(&np); // will not compile, &np is not right type
clearNode(&n); // will not compile, &n is not lvalue
C modify pointer
In C, same code would be like this (also works in C++, though above version would be better and cleaner):
void clearNode(struct node **n){
(*n)->field = 0; // modify caller's struct
*n = NULL; // set caller's pointer to NULL
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // will not compile, np is not right type
clearNode(&np); // OK, np becomes NULL, n.field becomes 0
clearNode(&n); // will not compile, &n is not of right type
C modify only struct
But if we write same code with just pointer, it will work just a bit differently:
void clearNode(struct node *n){
n->field = 0; // modify caller's struct
n = NULL; // change local parameter, which in this case has no effect anywhere
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // OK, except np is not modified, n.field becomes NULL
clearNode(&np); // will not compile, &np is not of right type
clearNode(&n); // OK, n.field becomes NULL
C++ modify only struct
And finally, same code in C++ would be cleaner this way:
void clearNode(struct node &n){
n.field = 0; // modify caller's struct
// no pointer, nothing to set to NULL
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // will not compile, np is not of right type
clearNode(&np); // will not compile, &np is not of right type
clearNode(&n); // will not compile, &n is not of right type
// these work, n.field becomes 0:
clearnode(n);
clearnode(*np);
Your question
So, the thing to take from above is, if you need to modify callers pointer, pass pointer to pointer (C and C++) or refrence to pointer (C++). This comes at a cost: you must always pass a modifiable pointer variable, and double indirection also has small overhead. Syntax for both is shown above.
If you do not need to modify callers pointer, but need to modify the struct contents, pass a pointer (C and C++) or reference (C++) to struct. Syntax for both is shown above.
Third case, when you don't need to modify anything, is not covered above, but has 3 basic alternatives: pass by value (C and C++, clean syntax but copies entire struct), pass by pointer to const (C and C++, a bit uglier syntax but passes just address) or pass by const reference (C++ only, clean syntax and passes only address).
To summarize, use double pointer (or reference to pointer) when you need to modify caller's pointer. Otherwise, pass a pointer (or a reference), or even a value if struct is small.

c++ - lists, pointers, and local variables

It should be a simple question, but for the life of me I can't finda solution online.
Simply put, creating an object and adding it to a list of pointers doesn't work for me - as soon as I try access the item in the list in a different method to where it was created, it gives an access violation.
So two questions:
1: What's the best way of doing this?
2: Subsequently, if it's not using pointer lists, what's the best way of removing from the list?
int main( int argc, const char* argv[] )
{
std::list<testClass*> list;
addClass(list);
std::cout << list.front()->a; //item added to list now longer accessible
}
void addClass(std::list<testClass*> list)
{
testClass* c = new testClass();
c->a = 1; c->b = 2;
list.push_back(c); //item still accessible here
}
class testClass
{
public:
int a;
int b;
};
You need to pass your list by reference, you are passing by value here and so it is making a copy of the container and working on that copy:
void addClass(std::list<testClass*> list)
If you modify it like so it should work as you want:
void addClass(std::list<testClass*> &list)
A first macroscopic error is that addClass shold take a std::list<testClass*> & so that it operates on the list contained in main, an not on a local copy.
After that, the entire design has to be better focalized:
Since testClass is not polymorphic (there is nothing virtual in it) what is the point to allocate them dynamically? It will probably be easier to let them contained as value directly in the list itself, havig a std::list<testClass>.
Or ... if you need dynamic allocation, you also have to consider deallocation, or you wil leak memory: if the list cotains pointers, it will destroy the pointer, not what they point-to.
So now, let's follow the two tracks:
Treating objects as values
You need a way to construct a testClass object from given values.
class testClass
{
public:
testClass(int a_, int b_)
:a(a_), b(b_)
{}
int a;
int b;
};
and now you can
void addClass(std::list<testClass>& list)
{
list.emplace_back(1,2);
}
and
int main()
{
std::list<testClass> list;
addClass(list);
std::cout << list.front().a;
}
Note how some * disappered!
Treating objects dinamically
Ok creating with new, but you have to take care of deletion.
One way is delete the pointed from list: just before the } in main...
for(auto p : list) delete p;
this will run across the list and call delete for each of the pointers, thus deallocating (and destroying) the object you allocated with new.
NOTE: This does not make the list empty: the list still contains the pointers, they simply point to invalid address. The pointers will be deallocated by the list at the exit from main
Another way is not to use plain pointers but smart pointer that delete themselves the content when they are destroyed.
This requires an std::list<std::unique_ptr<testClass> > as a container, so that you can
void addClass(std::list<std::unique_ptr<testClass> >& list)
{
list.emplace_back(new testClass(1,2));
}
Now, when main exits, the list gets destroyed with its own elements (the smart pointer) tha in turn will delete the new allocated objects.

Difference in passing by pointer -C++

What is the difference in the following code:-
int a;
int *p;
p=&a;
function(p);
and
int a;
function(&a);
I was reading a book where sometimes they have used the first code and sometimes the other. Its not a good book though (by a local author).
Will both codes work the same way or is there any difference?
Also is there any difference in terms of efficiency and does it matter that much?
Thanks
For a reference, the object must be already existing in order to reference it. As for a pointer, the object does not need to be already existing when declaring a pointer
Example:
int &i = 10; //Invalid
const int &i = 10; //Valid
also
you cannot declare an array of references:
int &tab[] = {2,3}; //Invalid
int * tab[] = {2,3}; //Valid
In practice, reference are mostly used as functions parameters and return values;
As far as I know compiler implements references as pointers. So there should be no difference in performance. But references are more strict and can protect you from making mistakes. For example you can't rebind references or can't perform arithmetic with them
Also some people prefere to pass pointers to the function that modify object. For example
void changeVal(int *p)
{
*p = 10;
}
They say it's more readable when you see:
changeVal(&var)
than
changeVal(var);
EDIT
You can think of reference as another name of the object it refers to. So all the changes made to reference are applied to the object. Here is an example:
void foo_copy(int a) //pass by copy
{
a = 10; //changes copy
}
void foo(int &a) //bass by reference
{
a = 10; //changes passed value
}
void foo(int *a) //pass an adress of a
{
(*a) = 10; //change a value pointed by a
a = nullptr; //change a (the pointer). value is not affected
}
In above two approaches, Both are using pointers, there is no difference except memory equal to sizeof(int *) will be allocated on stack for "int *p".
In case of call by reference, Refer. It seems you are beginner and learning things, you will come to know more about passing by reference and its use more while using copy constructor in classes.
The two code snippets should be equivalent when compiled with a modern compiler. The extra declaration and assignment (p=&a;) is optimised away.