I was trying this code:
int main()
{
char *ch="hello";
printf("%u",&ch);
return 0;
}
From the above printf() statement I have address of ch i.e 65524
My question is Can i find value if any address is given like *(65524) rather than *(&ch)?
Yes, you can:
printf("%d\n", *(unsigned char *) 65524);
If the address does not point to a valid object, you are invoking undefined behavior.
Related
Causes a segmentation fault:
int n;
int *variable = scanf("%d",&n);
printf("Printing :%d",*variable);
No problem:
int n;
scanf("%d",&n);
int *variable = &n;
printf("Printing :%d",*variable);
How to achieve the first one without the segmentation fault?
Assuming scanf was successful, it returns 1 (in general it returns the number of variables that were set).
In your second snippet you discard that (useful) information, and you are setting a pointer varaible to the address of n, which is perfectly valid. (If scanf returned 0 then n would be uninitialised, and the behaviour of your printf call undefined.)
In the first snippet you set a pointer to the int constant 0 or 1 depending on the return value of scanf. That's fine too, but the behaviour on dereferencing that pointer with
*variable
is undefined.
If you want to be flashy, and have a robust conversation with your code reviewer, you could use the expression separator operator and write
int n;
int *variable = (scanf("%d",&n), &n);
but that's naughty since, again, you discard the return value of scanf, and n could be uninitialised.
scanf("%d",&n); returns integer not pointer to integer. Below is the prototype of scanf.
int scanf(const char *format, ...);
When you point like below you are actually pointing to invalid address and it will lead to undefined behavior.
int *variable = scanf("%d",&n);
When you declare and initialize the pointer you assign the value to the pointer itself. The * is needed to show the compiler that you are declaring the pointer to the object of some type not the object itself
When you use the * later in the code you dereference that pointer.
void foo(void)
{
int a;
int *b = &a; //you assign the pointer `b` itself - no dereferencing
*b = 5; //you dereference the pointer and asssign the the referenced object
}
The "fresh" declared pointer (unless initialized with the reference to the valid object) does not point to the valid object and its dereferencing invokes the Undefined Behavior
void foo(void)
{
int a;
int *b = &a; //b is pointing to the valid object -> the variable `a`
int *c; //c is not pointing to valid object
int *d; //d is not pointing to valid object
c = malloc(sizeof(*c)); //now c is pointing to the valid object (if malloc has not failed of course)
*c = 5 // correct no UB
*d = 5; // incorrect - UB
*b = 5; //correct no UB
}
the syntax is similar (the * before the pointer name) but it does something completely different. I have noticed that it is a bit confusing for the beginners
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.
#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.
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.
#include <stdio.h>
struct audiocd {
char title[256];
int trackNo;
char type;
char publisher[256];
};
int main() {
struct audiocd* cdptr;
struct audiocd cdarray[4];
cdptr = cdarray;
printf("%d\n", &(cdarray[2]));
printf("%d\n", cdptr);
}
What is cdarray[2] & cdptr?
EDIT: Thanks, but if printf("%d\n", &cdarray) is 4291520 , is it possible to trace printf("%d\n", &(cdarray[2])) & printf("%d\n", cdptr)?
The overall effect of the program is simply undefined behavior. It's passing addresses to printf, but using the %d conversion, which expects an int. The mismatch causes undefined behavior.
In a typical case that int and a pointer happen to be the same size, it'll print out the address in cdptr and the address of cdarray[2].
If you want to print out those addresses, the obvious way is something like:
printf("%p", (void *)&cdarray[2]); // (void *)cdarray+2
printf("%p", (void *)cdptr);
As for what those expressions "are", they're addresses -- the addresses of the beginning of the array and the third element of the array, respectively.
thanks, but if printf("%d\n",
&cdarray) is 4291520 , is it possible
to trace printf("%d\n", &(cdarray[2]))
& printf("%d\n", cdptr).
If I got your question correctly, I think you want to infer the values of &(cdarray[2]) and &(cdptr) from value of cdarray.
As you assigned cdarray to cdptr, cdptr will store the starting address of the array. Now &(cdarray[2]) is just
cdarray + 2*sizeof(struct audiocd)
Also, as discussed above, %p should be used to print memory addresses instead of %d.