Use of Pointers - Very Confused! C++ [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm studying C++ using a few books, trying to learn SDL along side it. I understand that pointers "point" to a variable's memory address, and that they can be used to "reference" variables. But I don't understand their purpose? And how to use them properly?
I have a few examples from the book (I've added under the code that confuses me):
#include <iostream>
int main(void)
{
char string[6] = "Hello";
char* letter = string;
letter += 3;
OK, so there's a char pointer called 'letter' that points to the memory address of string. Then somehow we use the += operator on the pointer? How? What's going add? What are we adding the 3 to?
*letter = 'p';
And now here we use '*letter' instead of 'letter' - this means it's dereferenced, right? What does this actually DO?
string[4] = '!';
std::cout << string << '\n';
system("PAUSE");
return 0;
}
The rest of the code I understand.
Thanks for any answers!
George
EDIT: so let me get this straight - dereferencing a pointer (e.g. *pointer = 2;) is used to change the value of the variable (or array position, for that matter) when you want to?
EDIT 2: thanks to everybody's answers I almost completely understand the code I used as an example - however, I am still unsure as to the use of '&' (ampersand) in the context of pointers, and how/why they're used.

In this definition
char* letter = string;
letter is set to the address of the first element of character array string.
So *letter has value 'H'.
Let consider for example statement
++letter;
This statement "moves" the pointer to point to the next element of string. That is now the pointer points to the second element of string. Now the value pf *letter is 'e' because letter points to the second element.
Applying three times operator ++ as for example
++letter; ++letter; ++letter;
is equivalent to
letter += 3;
that is the pointer was moved three times and now it points to the second 'l' in string.
This statement
*letter = 'p'
will replace 'l' with 'p' and you will get that string now looks as
"Helpo"
After executing statement
string[4] = '!';
string contains
"Help!"
Instead of
string[4] = '!';
you could write
++letter;
*letter = '!';
Or you could combine these two statements in one statement
*++letter = '!';
EDIT: 'pointer' contains address of an object. When you write *pointer you access directly the object itself so *pointer = 2 change the object pointed by 'pointer'.
Also you should understand that if for example you have
int a[10];
int *p = a;
and let assume that the value of p (the address stored in p) is 4. Then expression ++p or p + 1 means that the pointer was "moved" to the next element of the array. It means that new value of p is not 5. The new value of p is p + sizeof( int ) that is 8 provided that sizeof( int ) is equal to 4.
In your example sizeof( char ) is always equal to 1 according to the C++ Standard.

You need a start from understanding pointers from beginning.
char string[6] = "Hello"; //string an array of 6 characters including null char
char* letter = string; //letter pointer pointing to string array,stores first char address
letter += 3; // Letter pointer in incremented by 3 char. Now it points to 4th char of string
*letter='p'; //replacing 4th char of string by p
cout<<letter; //prints "po";
Notes to help you
What are the barriers to understanding pointers and what can be done to overcome them?

Incrementing a pointer by an integer value (explained with an example):
Suppose you have int* x pointing to memory address 1000, and you increment it by 3: x += 3.
Variable x will now point to memory address 1000 + sizeof(int).
The size of int depends on your compiler; let's assume it is 4 bytes on your system.
So variable x is pointing to memory address 1012 (1000+3*4).
Now, suppose you use x in order to read the value at the memory address pointed by x:
int y = *x;
During runtime, the CPU will read 4 bytes from the memory address pointed by x, and store them into variable y, so that y will then contain the same value as the one stored in address range 1012-1015.

Then somehow we use the += operator on the pointer? How? What's going add? What are we adding the 3 to?
letter is in fact pointing to the first element of the string Hello. By adding 3 to it letter will point to the element 3 of the string (4th element).
And now here we use '*letter' instead of 'letter' - this means it's dereferenced, right? What does this actually DO?
Defreference means you are retrieving the value stored at the location letter points to.
ereferencing a pointer (e.g. *pointer = 2;) is used to change the value of the variable (or array position, for that matter) when you want to?
By doing *pointer = 2; you are storing 2 to the location pointer points to, ie, changing the value of the variable..

Related

pArray = pArray + 1; Can someone explain to me how this increments the array in C++? [duplicate]

This question already has answers here:
Why a pointer + 1 add 4 actually
(6 answers)
Closed 5 years ago.
I have been learning about using pointers with arrays. If I was to write this simple code:
string Array[3] = {"one", "two", "three"};
string *pArray = Array;
pArray = pArray + 1;
std::cout << *pArray << std::endl;
The output is 'two'
Can someone explain to me the workings of this? Why does the +1 change the position of the pointer to where "two" is in the array? I'd expect the +1 to be concatenated onto the end of the string pointer so I'd end up with something like '0x61feb01'.
How does the compiler know to increment the array and not just add a 1 on to the end of the pointer string memory location?
Why is adding an int to a string different here?
Thanks.
I think when you add "1" to your pointer, this "1" is not treated as an integer number in the process of addition. Notice that pointer is an address, now, when you add 1 to your pointer it becomes: the address it currently is+ONE COMPLETE SIZE of a string type. So for example if your string type takes 8 Bytes you're moving 8 Bytes forward in the memory and not 1 Bytes!
As to why "two" printed you should know that array elements are held in continuous groups of bytes in the memory thus when you add to the address of one of the elements you can get to the other elements. Array names are nothing but pointers themselves except that they are fixed pointers(you can't change their addresses). E.g. In (int myArr[10]) the name "myArr" is a pointer that points to the(has the address of the) first part in the ram that holds the first element and then using pointer arithmetic just as you've done in the above example of yours you can access the rest of the elements either.
As an ending note, these two are equal in this example array: (myArr[i]==*(myArr+i)), if you put 0 here instead of i, you get (myArr[0]==*myArr) which is exactly what I said earlier. I hope it helps.

Assigning value to the address pointed to by pointer? C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
So if an asterisk precedes the pointer name, it refers to the value of the address being pointed to
int anInteger = 30;
int* pointer = &anInteger;
*pointer;
While without having this operator preceding the pointer name, it refers to the value of the pointer itself, i.e. the address of what the pointer is pointing to
pointer;
(PLEASE correct me if I am wrong or if you just got some tips to share :) )
To me, this means that the above code can be translated to following with the assumption that the address of "myInteger" is 1234:
int* pointer = 1234;
30;
1234;
Now to what confuses me - Since that variables refer to locations in memory and names refer to the variables, it is odd to me that you do this when you want to change the value of a variable indirectly using a pointer:
*pointer = 15;
Because that could then be translated to 30 = 15, which does not look very valid..
Also, when you change the value of the variable directly, you do it like this:
anInteger = 33;
where "anInteger" would refer to the variable and thereby the memory address and because of that, I would translate this code to this:
1234 = 33;
SO, because of this, why don't you do this when assigning a new value to a variable indirectly using a pointer:
pointer = 33;
The exact question:
Why do you write *pointername = 33; instead of pointername = 33?
The exact question: Why do you write *pointername = newValue; instead of pointername = newValue?
These are two quite different things. (And you can do both.)
int i = 42;
int x = 23;
int * p = &i;
Now, I can change the content of the location I am pointing to...
*p = 123; // this changes the value of i
Or I can change the location I am pointing to.
p = &x; // now p points to x instead
The "natural" value of a pointer variable is a memory address. So, if I assign to the "naked" p, I am assigning a memory address (which I can obtain, for example, by using the & operator on a variable).
Using the operator *, I dereference the pointer variable. So, if I assign to the "combined" *p, I assign a value of the type pointed to (which ends up at the memory address contained in p).
How about this.
// i is the name of a memory location that now contains 5
int i = 5;
// p is the name of a memory location that contains the address of
// the memory location called i
int* p = &i;
// The memory location pointed to by p (which is also called i) now
// has the value 12 assigned to it
*p = 12;
Let's start with:
anInteger = 27;
rather than translating that to
1234 = 27
Let us write this as
[1234] := 27
which should be read as "the memory cell at address 1234 is assigned the value 27".
Now let us consider
pointer = &newValue;
Obviously (or perhaps not), we will translate that to
[1238] := 1242
which is read as "the memory cell at address 1238 is assigned the value 1242". (Where 1242 is the address of newValue)
Now we need a new way to write the statement where we don't want to alter the value in the pointer variable itself, instead we want to alter the variable that pointer is pointing to. We do that by prefixing with *:
*pointer = 17
Which gets translated into something like:
[[1246]] := 17
which we can read as "the memory cell whose address is given by the contents of memory cell 1246 is assigned the value 17".
The really hard thing to keep straight, is the difference between the value of the pointer, and the thing it is pointing at.
Every spot of memory has two fields, the address field as well as the data field.
For example, you may be at address 0x1234, but that address has a value as well
Address Value
0x1234 |||||| 0x1E
A variable knows about the address as well as the value. when you say
int var = 5;
Var has an address as well as a data field and the assignment operator says to replace the data field with 5.
Address Value
0x1234 |||||| 0x05
A *Pointer * on the other hand has a value of an address. when you write code like
int * varPtr = &var;
You are saying the Value of the varPtr variable is an address.
Address Value
0x1357 |||||| 0x1234
When you "de-point" a pointer like *varPtr, you are going to the address of the value in the pointer and talking about it's value.
*varPtr would be 0x05
varPtr would be 0x1234
var is also 0x05

Please explain arrays with pointers [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
So I'm new to programming and I want to understand the use of pointers in this program that my professor made.
#include <iostream>
using namespace std;
typedef int* IntPtr;
int main()
{
IntPtr p;
int a[10];
int i;
for(i = 0; i<10; i++)
a[i] = i;
p = a;
for(i = 0; i<10; i++)
cout << p[i]<< " ";
cout << endl;
}
Output:
0 1 2 3 4 5 6 7 8 9
According to what I read 'p = a' will pass the address of the first element of the array to 'p'. So I assume that the output would be all zeros. But when it printed it has the same elements as the array 'a'. It's like it passed the address of all the elements of a to p. Can someone please explain why. sorry if I can't explain the problem well but I hope you get my point.
Accessing an element through a[i] or p[i] with a being an array type and p being a pointer type is called the subscript operator, and you can read about its semantics, for example, in built in subscript operator:
...
The expression E1[E2] is exactly identical to the expression *(E1 + E2)
This means that p[i] is the same as *(p + i), i.e. it dereferences the value at memory address (p+i), whereas i is counted correctly using sizeof(int) since p is a pointer to int. And if p points to a, this is exactly the same as a[i], which again is the same as *(a+i), where a decays to a pointer to the first element in array a.
Hope it helps.
And I hope that your professor teaches the meaning of pointers, memory layout, dereferencing, and so on. IMHO, being confident with pointers and pointer arithmetic is a matter of months (actually years) rather than a matter of a "lesson".
It's actually a shame that students aren't explained how memory management works anymore...
If you allocate something, it physically ends up as a continuous piece of memory. That is: if you allocate an array, it's a sequence of bytes in one continuous block of memory.
Pointers are nothing more than a small block of memory (usually 4 or 8 bytes) that contains the address of something else. E.g. it points to data.
The array in this case is a sequence of bytes, and because int has 4 bytes, it's 40 bytes. Dereferencing an element in the array means reading integer at index X. (in other words: reading the 4 bytes from X*4 up to but not including (X+1)*4 -- or more precise: [X*4, (X+1)*4>).
Using a pointer means reading the contents that the address points to. In this case the pointer contains the address of the first element of the array, so reading *p means reading the first 4 bytes of the array. It's a synonym for p[0].
This basically works, because the data in the array is stored continuously and because no data is copied. So, if you write a[2] = 2, it simply overwrites bytes 2*4 to (2+1)*4 (more precise: [2*4, (2+1)*4>) in your memory block that is named your array. It doesn't make a copy, change the address in p or anything else.
PS: One important detail to note is that in C++ allocation of things like integer arrays doesn't mean setting everyting to 0. It just allocates a slab of memory with the right type; nothing more.

Hex values printing with different padding through char pointer in different instances [duplicate]

This question already has answers here:
Strange output when printing the value 0x89 (-119)
(3 answers)
Closed 8 years ago.
#include<stdio.h>
int main()
{
unsigned int a=0xabcdef12;
char *c=(char *)&a;
int i;
for(i=0;i<4;i++)
{
printf("%x.....%x\n",*c,c);
c++;
}
return 0;
}
O/p:
12.....bfad5bd4
ffffffef.....bfad5bd5
ffffffcd.....bfad5bd6
ffffffab.....bfad5bd7
If you see during first print, it is printing 12 but in all the subsequent prints it is printing correct values but padded with ffffff. Can someone explain this difference??
You are messing with pointers. Be careful out there. The line
char *bit_longer_name=(char *)&a;
says that "gimme pointer to CHAR type data array, and call it 'bit_longer_name'. The array initializes at variable 'a' address". Now when you do
bit_longer_name++
it actually travels that pointer forward in memory -- goes to next element in a array -- like my_char_array[i] does. The print you have there:
printf("%x.....%x\n",*c,c);
The first part prints the "value of the current array cell i am pointing to", and you are actually passing invalid value for the printf (you should get warning from that!), that causes the compiler to read over from the memory spot pointed by 'c' (-> its working in the first place).
The second part on the other hand is the "address i am pointing to with 'c'", and it travels forward as you can see.

What are the ramifications of simply checking a pointers value in a conditional statement?

Here goes my code:
#include <iostream>
using namespace std;
int countX(char*, char);
int main() {
char msg[] = "there are four a's in this sentence a a";
//char *ptr = msg; // <----- question 2!
cout << countX(msg, 'a');
cin.get();
}
int countX(char* ptr, char x) {
int c = 0;
for (; *ptr; ptr++) {
if (*ptr == x) c++;
}
/*
while(*ptr) {
if(*ptr==x) c++;
ptr++;
}
*/
return c;
}
I was wondering a few things specifically regarding safe practice and pointers:
My conditional statement in the for-loop ; *ptr ;, is this safe practice? Will it every break if there happens to be something stored in the memory address right next to the last element in the array? Is that even possible? How does it know when to terminate? When is *ptr deemed unacceptable?
(concerning the commented out char *ptr = msg; in the main): I understand a pointer and an array are very similar, however, is there a difference between passing the actual array to countX vs. passing a pointer (which points to the beginning of the array?).
In countX I've provided two different ways to approach the simple problem. Is one considered superior over the other?
Q My conditional statement in the for-loop ; *ptr ;, is this safe practice?
A Yes, most of the time. See below for more details.
Q Will it every (I know you meant ever) break if there happens to be something stored in the memory address right next to the last element in the array?
A Yes.
Q Is that even possible?
A Yes. You can easily access the memory one past the last character of the array and make it something other than the null character.
Q How does it know when to terminate?
A It will terminate when you encounter the terminating null character of a string. If the null character has been replaced by something else, the behavior is going to be unpredictable.
Q When is *ptr deemed unacceptable?
A If the string length is len, it is OK to set ptr in the range msg and msg+len. If ptr points to anything beyond that range, the behavior is undefined. Hence, they should be considered unacceptable in a program.
Q (concerning the commented out char *ptr = msg; in the main): I understand a pointer and an array are very similar, however, is there a difference between passing the actual array to countX vs. passing a pointer (which points to the beginning of the array?).
A No. They are identical.
Q In countX I've provided two different ways to approach the simple problem. Is one considered superior over the other?
A No they are not. It comes down to personal taste. I happen to like to use for loops while I know people that like to use while loops.
Q1 : My conditional statement in the for-loop ; *ptr ;, is this safe practice? Will it every break if there happens to be something stored in the memory address right next to the last element in the array? Is that even possible? How does it know when to terminate? When is *ptr deemed unacceptable?
Ans : When used with c-style strings, yes it is a safe practice. Any c-style string necessarily ends with '\0', which is basically 0. The behavior is undefined when the '\0' is not there. So the loop would break at the end of the string. *ptr would never terminate if it is anything other than a c-style string. For example, a c-style "hello" is actually an array containing 'h', 'e', 'l', 'l', 'o', '\0'. So, the loop exists at '\0', never accessing the memory after it.
it is possible to access the memory after the last element of an array. For example,
int a[5] = {0,1,2,3,4,5};
int *p = a+5;
p is accessing the element after the last element of the array a.
Q2 :(concerning the commented out char *ptr = msg; in the main): I understand a pointer and an array are very similar, however, is there a difference between passing the actual array to countX vs. passing a pointer (which points to the beginning of the array?).
Ans : Arrays and pointers are not exactly similar. Its just that an array name is nothing but a constant pointer pointing to the first element of the array. Consider the previous example i wrote. In that, a[3], 3[a], *(a+3) and *(p+3), all refer to the same element. Since you are passing by value, the value of the constant pointer msg would just be copied to ptr. So, no, it would make no difference.
Q3 : In countX I've provided two different ways to approach the simple problem. Is one considered superior over the other?
Ans : I am not an expert, but i'd say no.
Also, you probably dont need the cin.get().
This is very bad practice.
What you're doing in the for condition is basically if (*ptr), in other words, does the memory pointed to by ptr contain a non-zero value?
So if the memory location after the string contains a non-zero value (maybe from another variable using the space) or a garbage value then your loop could go infinite, or give you an incorrect value. Instead you should run the loop from 0 to the length of your string.