pointers, double pointers and triple pointers in c [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can someone tell me the flow of references in the second printf statement in the given code?
#include<iostream>
using namespace std;
char *c[] = {"ENTNG","NST","AMAZI","FIRBE"};
char **cp[] = {c+3,c+2,c+1,c};
char ***cpp = cp;
int main(){
cout<<(**++cpp);
cout<<(*--*++cpp+3);
cout<<(*cpp[-2]+3);
cout<<(cpp[-1][-1]+1);
return 0;
}
I am trying to understand the concept of pointers, double pointers and triple pointers. Can please somebody tell me how this code works and the concept behind the solution? Thanx in advance.

A single pointer is that data type which can point to a memory location of a particular data type.. In this case, it is char so we assume it is a char pointer and it can point only to a char variable, that is, it can hold address of a character variable only.
A double pointer can hold the address of a single pointer, and a triple pointer can hold the address of a double pointer.
In your code, the first pointer 'c' is a double pointer which holds cstrings in itself. cstrings are single char pointers. then 'cp' and 'cpp' both are triple pointers.
As for the rest of the code,it is pretty messed up and looks like a nightmare. You had better read some resource on pointers and basic C++ programming. I would recomment Programming abstractions in c++ by Sir Eric Roberts from Stanford.
Also see smart pointers.

Related

&temp and *temp in c++

I am new to C++ and trying to convert string into integer. I was using atoi but there are some restrictions so I start using strtol which works perfectly. However, I would like to learn more on *temp and &temp (I have google and learn that it is a temporary space for storage) but would like to learn the difference and when to use which.
char *temp;
int m = strtol (argv[1],&temp,10);
if (*temp != '\0')
*temp is a pointer to a variable named temp and &temp takes the address of that variable
First of all jessycaaaa welcome to Stackoverflow.
I am new to C++ and trying to convert string into integer.
For me this looks like plain C-code. You can compile this with a C++ compiler though.
I was using atoi but there are some restrictions so I start using strtol which works perfectly.
Since you get an undefined behavior using atoi when argv[1] contains something different than a number, strtol is an approach to go for. If you share us a bit more code, we would help you better on your questions.
However, I would like to learn more on *temp and &temp (I have google and learn that it is a temporary space for storage) but would like to learn the difference and when to use which.
First of all you have to distinguish between use and declaration
char *temp;
Here you declare (*-symbol in declaration) a pointer named temp of type char. A pointer is a variable which stores the memory address (where it is pointing to). Here you did not define an address so it most likely will point a random space, but then
int m = strtol (argv[1],&temp,10);
you pass the address of the pointer (&-symbol, use-case, address-of operator) to strtol, so you get an address pointing to the part of the argv[1] where the number literals end, that is all fine. The function also returns the numerical value of the read string as long and is converted to an int.
if (*temp != '\0')
Here you access the value of what the address is pointing to (*-symbol, use-case, dereference operator). \0 is normally set as indication for a null-terminated string. So you are asking if the previously read end part has the null-termination character.
You know what: in C++ there are more elegant ways to accomplish that using stringstreams:
std::stringstream
Just an idea if you don't want to handle too much string manipulation in C and annoyances with pointers.
Also I would read a good book about C (not C++). C++ has also the references don't get confused by those. If you dominate the pointer-concept of C, I'm pretty sure everything else will be very clear for you.
Best regards
* and & are one of the first hurdles that programmers new to C and C++ have to take.
To really understand these concepts, it helps to know a bit more about how memory works in these languages.
First of all: C++ is just C but with classes and many other additional features. Almost all C programs are valid C++ programs. C++ even started out as a language that was compiled to C first.
Memory is, roughly speaking, divided in two parts, a 'stack' and a 'heap'. There are also other places for the code itself and compile-time constants (and maybe a few more) et cetera but that doesn't matter for now. Variables declared within a function always live on the stack. Let's see this in action with a simple example and analyse how memory is organized to build a mental model.
#include <iostream>
void MyFunction() {
int intOnStack = 5;
int* intPtrOnStack = new int(6); // This int pointer points to an int on the heap
std::cout << intOnStack << *intPtrOnStack;
delete intPtrOnStack;
}
int main() { MyFunction(); }
This program prints 56 when executed. So what happens when MyFunction() gets called? First, a part of the stack is reserved for this function to work with. When the variable intOnStack is declared within the function, it is placed in this part of the stack and it is initialized with (filled with) the int value 5.
Next, the variable intPtrOnStack is declared. intPtrOnStack is of type int*. int*'s point to int's by containing their memory-address. So an int* is placed on the stack and it is initialized with the value that results from the expression new int(6). This expression creates a new int on the heap and returns the memory-address of this int (an int*) to it. So that means that intPtrOnStack now points to the int on the heap. Though the pointer itself lives on the stack.
The heap is a part of memory that is 'shared' by all functions and objects within the program. The stack isn't. Every function has its own part of the stack and when the function ends, its part of the stack is deallocated.
So int*'s are just memory-addresses of int's. It doesn't matter where the int lives. int*'s can also point to int's on the stack:
#include <iostream>
void MyFunction() {
int intOnStack = 5;
int* intPtrOnStack = &intOnStack; // This int pointer points to intOnStack
std::cout << intOnStack << *intPtrOnStack;
}
int main() { MyFunction(); }
This prints 55. In this example we also see the &-operator in action (there are several uses of & like the bit-wise-and, I'm not going into them).
& simply returns the memory-address (a pointer!) of its operand. In this case its operand is intOnStack so it returns its memory-address and assigns it to intPtrOnStack.
So far, we've seen only int* as types of pointers but there exist pointer-types for each type of object that has a memory-address, including pointers. That means that a thing like int** exists and simply means 'pointer to a pointer to an int'. How would you get one? Like this: &intPtrOnStack.
Can pointers only live on the stack? No: new int*(&intPtrOnStack). Or new int*(new int(5)).

Dealing with pointer arrays

I am playing around with arrays as pointers.
#include<iostream>
#include<cstring>
using namespace std;
int main(){
string *myarray[20];
*myarray[0]="Ich denke sein";
*myarray[1]="Ich sehe sein";
cout<<*myarray[0]<<endl;
cout<<*myarray[1]<<endl;
return 0;
}
The above code compiles but while executing, there is error, the program hangs. When I debugged using visual studio, it said memory allocation error. What is the error here?
As I know, I am dealing with values refered by pointers everywhere.
You have allocated an array of 20 pointers to strings. But you haven't allocated any memory for what the pointers point to. Rather than pursuing this and using new to allocate memory for the strings, it would be better instead to allocate memory for the strings themselves in the array and you will be fine.
string myarray[20];
myarray[0]="Ich denke sein";
myarray[1]="Ich sehe sein";
cout<<myarray[0]<<endl;
cout<<myarray[1]<<endl;
In response to your comment, to make your program work as is, set the pointer to point to a new string object
myarray[0]=new string("Ich denke sein");
myarray[1]=new string("Ich sehe sein");
The other lines of your program remain unchanged. Note
the remaining myarray[i], for 2<=i && i<20 will still be garbage. (It would be neater to set them to 0 or nullptr in a for loop.)
you also ought to delete the objects you've allocated. (You could use a for loop over the whole array to do this if you'd cleared the rest of the pointers first.)
as other answers have commented, in modern C++ it is best not to use pointers directly unless you absolutely have to. And you would also typically prefer to use a vector for arrays rather than using the built-in type (in C++11 the array type can be used for arrays where you know the length at compile time).
You have an array of uninitialized pointers:
string *myarray[20];
Then you treat it as if the pointers pointed to valid objects:
*myarray[0]="Ich denke sein";
This is undefined behaviour. It is unrelated to arrays. It is the same as doing this:
std::string* s;
*s = "boom!";
Besides that, you really should #include <string> if you want to use std::string.
First, you didn't include the right header. For string, you should:
#include <string>
Second, the program hangs because you're assigning data to where the pointer is pointing to. So where does myArray[0] point to? You don't know, I don't know, no one knows. It seems you didn't get the grasp of what pointers are all about, regardless of whether you're dealing with arrays of them or not.
To use a pointer, it must point somewhere valid. If you don't do that, then you can't dereference the pointer and assign data. It's that simple.
May be the problem is that those pointers aren't pointing to any addres in the memory. Pointers should be initialized to somewhere using the "address of operator" (&) or putting them in the free memory, using the "new" keyword, and if you do so, don't forget to free that memory using the "delete" keyword. Hope that works for you.
What is the error here?
The error is, that you are using pointers ;-)
#include <string>
#include <iostream>
int main() {
std::string myarray[2] = {
{ "Ich denke sein" }, { "Ich sehe sein" } };
std::cout << myarray[0] << std::endl;
std::cout << myarray[1] << std::endl;
return 0;
}
What is the reason behind using pointer? In C++ you mostly never use pointers.
Kind regards - Andreas
You have declared an array of 20 pointers. You will have to allocate memory to the pointer before assigning a value at the location to which it points.
string* myarray[20];
for(int i = 0; i < 20; i++) {
myarray[i] = new string();//allocating memory to the pointer
}
*myarray[0]="Ich denke sein";
*myarray[1]="Ich sehe sein";
cout<<*myarray[0]<<endl;
cout<<*myarray[1]<<endl;
Pointers are used to point to memory addresses, like this:
String text ="hello";
String *myptr = &text;
Now the pointer points to the address of the string text.
Or you can use new keyword to allocate memory for an array of pointers. new returns you a pointer to the first position of the array. Like this:
int *myptr = new int[20];
But remember to use delete, to deallocate the allocated memory later. Like this:
delete[] myptr

Address of address of array

If I define an variable:
int (**a)[30];
It is pointer. This pointer points to a pointer which points to an array of 30 ints.
How to declare it or initialize it?
int (**a)[10] = new [10][20][30];
int (**a)[10] = && new int[10];
All doesn't work.
The direct answer to your question of how to initialize a (whether or not that's what you actually need) is
int (**a)[10] = new (int (*)[10]);
I don't think this is actually what you want though; you probably want to initialize the pointer to point to an actual array, and either way std::vector is the better way to do it.
If you want an answer to the question as it stands, then you can do this kind of thing:
int a[30];
int (*b)[30] = &a;
int (**c)[30] = &b;
But it's unlikely to be what you want, as other people have commented. You probably need to clarify your underlying goal - people can only speculate otherwise.
Just to follow on from MooingDuck's remark, I can in fact see a way to do it without the typedef, but not directly:
template <typename T>
T *create(T *const &)
{
return new T;
}
int (**a)[30] = create(a);
It's not pretty though.
What do you expect to get by writing &(&var)? This is an equivalent of address of address of a block of memory. Doing things like this just to satisfy the number of * in your code makes no sense.
Think about it - how can you get an address of an address? Even if, by some sheer luck or weird language tricks you manage to do it, there no way it will work.

Whats the difference between void* and void * [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In C, why is the asterisk before the variable name, rather than after the type?
Declaring pointers; asterisk on the left or right of the space between the type and name?
I have been using pointers for a while and used to declare pointers like
int *x;
But noticed thru some code that, the * seems to be after data type in some cases, like
void* setValue(){
/* */
}
What's the difference and why it's used like that
Semantically nothing. It is style.
The advantage for putting the star right next to the variable is preventing this common error:
char* str1, str2;
/* str2 is a char, not char* ! */
char *str1, *str2;
/* ok */
This issue is non-existent with return types, so it matters even less there.
It's exactly the same as the difference between a+b and a + b - that is, there is no difference. Whitespace has no meaning at all, except when it's needed to separate tokens.
no difference, in some cases its better to keep it to the right:
int* p1,p2;
looks like p1 and p2 ara pointers, while only p1 is,
int *p1,p2;
now it looks a bit better, but good style is to split it to separate lines:
int *p1;
int p2;
No semantic difference.
Usually it is recommended to keep the * next to the type because the real type of x is void *. However this is syntactically false, since C/C++ binds the star to the variable name.
int *x, y; // declare one pointer to int x and one int y
Personally I try to keep the * in the middle
int * x;
A pointer to void, noted as void* is a generic opaque pointer. You can pass it (as argument, result, thru variables, fields...) and compare it but the only way to get the pointed data is to cast it appropriately. An inappropriate cast is undefined behavior and can crash your program.
As for the space before or after the * denoting pointers in types, it is a style thing. Spaces are not really significant, except as token separator (and * is a token by itself).
I strongly suggest to be consistent with spacings. You could use tools like e.g. indent to indent your source code (and passing -T options to it help good indentation of type names). The GNU indent tool is normalizing spaces and has many options to tune its behavior (you might put them in a .indent.pro file). For C++ code, consider using astyle instead of indent.

Dereferencing pointer to array when debugging in XCode 4.2

I'm using XCode to follow along in an intro to programming C++ class. No grade involved, I'm simply living vicariously through the eyes of others. Now that we've reached the subject of pointers I'm having trouble keeping track of where I am. If I pass a pointer to a dynamic array into a function how can I dereference that pointer to see what's actually being held in the various positions of the array. My code is compiling, but a couple of the functions are returning garbage. A clear indication that something isn't point to the right place.
Thanks in advance!
--John
It's likely that some code will be needed to further understand your problem, but from what I understood, here is what you need.
#include <iostream>
void f(int *array){
std::cout<<array[5];
}
int main(){
int* array = new int[10];
array[5] = 20;
f(array);
return 0;
}
This will print "20".