Learning C - Pointers and memory addressing - c

I am learning C programming and I have a simple question about pointers...
I used the following code to play around with pointers:
#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
printf("%x\n",c);
return 0;
}
When I print the value of C, I get back a 0. However, when I print &c (i.e. printf("&x\n",&c) I get an address in memory...
Shouldn't I be getting an address in memory when printing the pointer (i.e. printf("%x\n",c)?
--- EDIT ---
#include <stdio.h>
#include <stdlib.h>
int main (int argc, const char * argv[]) {
char * a = malloc(11);
printf("String please\n");
scanf("%s",a);
printf("%s",a);
}
The question is, why does printf("%s",a) returns the string instead of the address that is stored in a?
Shouldn't I use *a to follow the pointer and then print the string?

your current program is not correct. You define variable and do not set value before first use. the initial value is not guranteed for c, but you are lucky and it is equal to 0. It means that c points to nowhere. when you print &c you print address of variable c itself. So actually both versions print address.

printf is actually quite a complex function and can be made to do all sorts of tricks by giving it the right format specifier.
In your string example:
printf("%s", a)
the "%s" tells the printf function that the following variable should be treated as a string. In C, a string is a pointer to one or more char, terminated by a char containing 0. This is a pretty common request, which is why printf supports a format specifier "%s" that triggers this relatively complex behavior. If you want to print the address contained in the string pointer you have to use the format you found earlier:
printf("%x\n",a);
which tells printf to treat the contents of a as an unsigned integer, and print it in base 16.
*a would just be the value pointed to by a, which is just a single character.
You could print the single character with
printf("%c", *a);

Having int* c; If you print value of c, you get back a value that should be interpreted as a memory address of an integer value. In you example it might be 0 or something completely different as you are not initializing c.
If you print &c you get memory address of the pointer c (stored in stack).

#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
int a=10;
c = &a;
printf("%x\n",c);
return 0;
}
This may clarify what happens when you make the int pointer point to something in memory.

Related

working with char pointer and integer pointer

My question is about dereferencing a char pointer
Here is my code -
#define MAX 10
char s[80]="Hello";
int main(){
char *stackValue;
stackValue=&s;//here I assined the address of s to stackValue
if(!stackValue){
printf("No place for Value");
exit(1);
}
else{
printf("\n%s",*stackValue);//This doesn't work with * before it
printf("\n%s",stackValue);//This works properly
}
return 0;
}
In the above code I have assigned the address of S[] to stackValue and when I am printing *stackValue it doesn't work ,
But If I print only 'stackValue' That works.
When I do same thing with Integer
int main(){
int i=10, *a;
a=&i;
printf("%d",*a);//this gives the value
printf("%d",a)//this gives the address
return 0;
}
Is printing char pointer and integer pointer is different. When I use * in int value it gives the value but gives an error when I use it as a char pointer.
Help me out?
With the first code snippet:
stackValue=&s; is incorrect given s is already an array to char. If you write like that then stackValue becomes pointer to pointer to char (not pointer to char).
Fix that by changing to stackValue=s;
Also, again %s expect a pointer to char (NOT pointer to pointer to char) - that explains why this doesn't work
printf("\n%s",*stackValue); // this doesn't work
You need printf("\n%s",stackValue); instead.
With the second code snippet.
a=&i; is ok because i is a single int, NOT an array.
What you are trying to do is this:
int main(void)
{
char a_data = "Hello, this is example";
char *pa_stack[] = {a_data};
printf("We have: %s\n", *pa_stack);
}
The "%s" format specifier for printf always expects a char* argument.
so this is working and correct statement
printf("\n%s",stackValue);
and in first statement you are passing value so it will give you undefined behaviour.

Why does the C program give me this output when printing a pointer?

#include <stdio.h>
int main()
{
int i;
int buf[10];
char *p ;
p = 4;
printf("%d",p);
return 0;
}
Output:
4
How come it is 4? I was expecting some address value. Can you please help me understand it?
This is undefined behavior, because %d expects an integer.
The reason why you see this output is that pointers have enough capacity to store small integer numbers, such as 4. If by coincidence the pointer size on your system matches the size of an integer, printf would find a representation that it expects at the location where it expects it, so it would print the numeric value of your pointer.
The proper way to print your pointer would be with the %p format specifier, and a cast:
printf("%p", (void*)p);
I was expecting some address value.
You would get an address value if you had assigned p some address. For example, if you did this
char buf[10];
char *p = &buf[3];
printf("%p", (void*)p);
you would see the address of buf's element at index 3.
Demo.

const char **a = {"string1","string2"} and pointer arithametic

main()
{
const char **a = {"string1","string2"};
printf("%c", *a); /* prints s */
printf("%s", a); /* prints string1 */
printf("%s", a+1);/* prints ng1 */
}
GCC v4.8.3 prints "%s" for the last printf, where as http://codepad.org/ prints "ng1".
I thought that the code will create an array of pointers to two strings and the base address assigned to a, which allows normal pointer arithmetic. but it seems that there is something wrong with the assumption.The first printf suggests that my assumption is wrong. can anyone explain why this behavior is observed? ( note that VS 2012 has thrown an error saying too many initalizers where as GCC has thrown a warning for incompatible pointer assignment). I am aware of the warning due to incompatible pointer assignment.
const char **a is not an array of pointer to two strings. It declares a to be a pointer to pointer to const char.
const char **a = {"string1","string2"}; //No memory is allocated to store string literals
will invoke undefined behavior and you may get either expected or unexpected results.
To declare a as an array of two pointers you need to change the declaration as
const char *a[] = {"string1","string2"};
The memory range in your program's stack looks like this: (notice that it is not allocated before assignment which is wrong)
char** a = {s, t, r, i, n ,g, 1, \0, s, t, r, i, n, g, 2, \0}
Therefore when you print the command:
printf("%c", *a);
You are dereferencing the first character of the string which is 's'.
On the other hand, when you print the command:
printf("%s", a);
you are printing a string that starts at pointer a and finishes at '\0'. That's why you see the output 'string1'.
Lastly, when you type "a+1" you increase the pointer in one step (example here: How to increment a pointer address and pointer's value?). in this case because char** is a pointer, and every pointer is 4 byte, the "+1" jumps 4 chars forward.
Therefore when you print the command:
printf("%s", a+1);
The printf starts at the pointer 'a' + 4 bytes and ends at '\0'. That's why the output is 'ng1'.
Hope it was clear enough.
This is due to the following peculiar initialization performed by GCC.
please see int q = {1,2}; peculiar initialization list. the statement const char **a = {"string1","string2"}; results in a being treated as if const char **a = "string1". this solves the mystery as *a would print 's', a would print string1.

Need help understanding char and int pointers

In this code to print the value of int and char pointer variables, why do I access them differently? For the char pointer I write sampleclient but for the int I write *intid. Why does one use * but not the other?
int main()
{
char client[] = "ABCD";
int intid = 10;
samplepass(&client, &intid);
return 0;
}
void samplepass(char *sampleclient, int *intid)
{
printf("%s %d\n", sampleclient, *intid);
}
This is because %s format specifier expects a char pointer, while %d expects an integer argument. If you want to see the value of the pointers themselves(i.e. the address they point to) use %p.
In C, you can't pass a string (character array) to a function like printf, so you do the next best thing: pass it its address in memory. The function can then treat the memory address like an array using pointer arithmetic. So the way printf reads strings is by taking in a pointer to the string. Then %s displays the dereferenced string (ABCD here), not the pointer address (which you could get by using %p instead of %s).
The integer problem is more straightforward: the * in *intid means 'get the value stored at this address'. That's why it prints out 10, not the memory address.
The 'correct' format specifier to get a memory address is %p. But you could write:
int main()
{
char client[] = "ABCD";
int intid = 10;
samplepass(&client, &intid);
return 0;
}
void samplepass(char *sampleclient, int *intid)
{
printf("%d %d\n", sampleclient, intid);
}
On my machine, the output was
-2140958000 -2140958004
(and those are the addresses in memory of client and intid). Substituting %p for %d gives nicely formatted pointers with a 0x in front and conforms to the standard, so I'd use that.
For an output that looks like:
ABCD 10
change your line
from samplepass(&client,&intid);
to samplepass(client,&intid);

Issue with string and pointers

Can somebody tell me why this program does not work?
int main()
{
char *num = 'h';
printf("%c", num);
return 0;
}
The error I get is:
1>c:\users\\documents\visual studio 2010\projects\sssdsdsds\sssdsdsds\sssdsdsds.cpp(4): error C2440: 'initializing' : cannot convert from 'char' to 'char *'
But if I write the code like that:
int main()
{
char num = 'h';
printf("%c", num);
return 0;
}
it's working.
char *num = 'h';
Here, the letter 'h' is a char, which you are trying to assign to a char*. The two types are not the same, so you get the problem that you see above.
This would work:
char *num = "h";
The difference is that here you're using double-quotes ("), which creates a char*.
This would also work:
char letter = 'h';
char* ptrToLetter = &letter;
You should read up on pointers in C to understand exactly what these different constructions do.
char * is a pointer to a char, not the same thing than a single char.
If you have char *, then you must initialize it with ", not with '.
And also, for the formatting representation in printf():
the %s is used for char *
the %c is only for char.
In thefirst case you declared num as a pointer to a char. In the second case, you declare it as a char. In each case, you assign a char to the variable. You can't assign a char to a pointer to a char, hence the error.
'h' = Char
"h" = Null terminated String
int main()
{
char *num = "h";
printf("%s", num); // <= here change c to s if you want to print out string
return 0;
}
this will work
As somebody just said, when you write
char *num = 'h'
The compiler gives you an error because you're trying to give to a pointer a value. Pointers, you know, are just variables that store only the memory address of another variable you defined before. However, you can access to a variable's memory address with the operator:
&
And a variable's pointer should be coerent in type with the element pointed.
For example, here is how should you define correctly a ptr:
int value = 5;
//defining a Ptr to value
int *ptr_value = &value;
//by now, ptr_value stores value's address
Anyway, you should study somewhere how this all works and how can ptrs be implemented, if you have other problems try a more specific question :)
When you are using char *h, you are declaring a pointer to a char variable. This pointer keeps the address of the variable it points to.
In simple words, as you simply declare a char variable as char num='h', then the variable num will hold the value h and so if you print it using printf("%c",num), you will get the output as h.
But, if you declare a variable as a pointer, as char *num, then it cannot actually hold any character value. I can hold only the address of some character variable.
For example look at the code below
void main()
{
char a='h';
char *b;
b=&a;
printf("%c",a);
printf("%c",b);
printf("%u",b);
}
here , we have one char variable a and one char pointer b. Now the variable a may be located somewhere in memory that we do not know. a holds the value h and &a means address of a in memory The statement b=&a will assign the memory address of a to b. Since b is declared as a pointer, It can hold the address.
The statenment printf("%c",b) will print out garbage values.
The statement printf("%u",b) will print the address of variable a in memory.
so there's difference between char num and char *num. You must first read about pointers. They are different from normal variables and must be used very carefully.

Resources