I am new to C and have some questions about the pointer.
Question 1 What`s differences b/w the following two? Which way is better to initialize a pointer and why?
int *p=NULL;
int *p;
#include <stdio.h>
void main()
{
char *s = "hello";
printf("%p\t%p",s);
//printf("%p\t%p",&s) it will give me unpredictable result every time
//printf("%p\t%p",(void *)&s) it will be fine
//Question3: why?
}
Question 2: I try to google what is %p doing. According to my reading, it is supposed to print the pointer. It that mean it print the address of the pointer?
Question 1, these are definitions of pointer p. One initializes the pointer to NULL, another leaves it uninitialized (if it is local variable in a function, and not global variable, global variables get initialized to 0 by default). Initializing with NULL can be good, or it can be bad, because compiler can warn you about use of uninitialized variables and help you find bugs. On the other hand compiler can't detect every possible use of uninitialized variable, so initializing to NULL is pretty much guaranteed to produce segmentation fault if used, which you can then catch and debug with a debugger very easily. Personally I'd go with always initializing when variable defined, with the correct value if possible (if initialization is too complex for single statement, add a helper function to get the value).
Question 2, %p prints the address value passed to printf. So printf("%p", pointer); gets passed value of variable pointer and it prints that, while printf("%p", &pointer); (note the extra & there) gets passed address of the variable pointer, and it prints that. Exact numeric format of %p is implementation defined, it might be printed just as a plain number.
Question 3 is about undefined behavior, because format string has more items than what you actually pass to printf. Short answer is, behavior is undefined, there is no "why". Longer answer is, run the application with machine code debugger and trace the execution in disassembly view to see what actually happens, to see why. Note that results may be different on different runs, and behavior may be different under debugger and running normally, because memory may have different byte values in different runs for various reasons.
1) The first is an initialization (to NULL in this case) the second is only a declaration of p as a pointer to int, no initial value is assigned to p in this case. You should always prefer an initialization to prevent undefined behavior.
2) You should cast to void* when using %p to print out a pointer (beware that you are using it too many times in your format specifier). The memory address to which p points is printed.
1)
int *p = NULL
defines and initializes a pointer 'p' to NULL. This is the correct way to initialize pointers in order to get "Seg Fault" if you forget to assign a valid address to this pointer later.
int *p
Only defines a pointer "p" with an unknown address. If you forget to assign a valid value to this pointer before using it, then some compilers will notify you about this mistakes while some others will not and you may access a non-valid address and get a run time error or undefined behaviour of the program.
2) "%p" is printing the address where the pointer is points. Since the pointer holds an address, then "%p" prints this address.
printf("%p\t%p",s);
So the first "%p" will print the address where the pointer "s" points which is the address which stores the string "hello". However, note that you are using twice "%p" but you providing only one pointer to print its address !!
Most compilers will not scream about this cause it is effect-less; however try to avoid it.
Answer1 :
int *p=NULL;
p is a pointer to a int variable initialized with NULL. Here NULL means pointer p is not pointing to any valid memory location.
int *p;
p is a pointer to a int variable. p in uninitialized. Reading uninitialized variables is Undefined Behavior. (one possibility if try to use is that it will throw a segmentation fault)
Answer2:
It prints content of pointer. I mean base address of string "hello"
The main difference is that in *p = NULL, NULL is a pre-defined and standard 'place' where the pointer points.
Reading from Wikipedia,
The macro NULL is defined as an implementation-defined null pointer constant,
which in C99 can be portably expressed as the integer value 0
converted implicitly or explicitly to the type void*.
This means that the 'memory cell' called p contains the MACRO value of NULL.
If you just write int *p, you are naming the memory cell with the name p but this cell is empty.
Related
Can anybody tell me, the meaning of wild pointer in C, how to obtain it and is this available in C++?
The standard does not define or use the term "wild". I'd be careful "correcting" other people's opinions about what it means, and I'd especially avoid quoting random non-normative internet junk to support my position.
To me, it would mean a pointer that neither refers to a legitimate object, nor is NULL. Possible sources of these types of pointer values might include uninitialized pointer objects, objects that have ceased to exist, computed pointer values, improperly aligned pointer values, accidental corruption of the pointer itself, or what it pointed to, etc.
int main(void)
{
int *p; // uninitialized and non-static; value undefined
{
int i1;
p = &i1; // valid
} // i1 no longer exists; p now invalid
p = (int*)0xABCDEF01; // very likely not the address of a real object
{
int i2;
p = (int*)(((char*)&i2) + 1); // p very likely to not be aligned for int access
}
{
char *oops = (char*)&p;
oops[0] = 'f'; oops[1] = 35; // p was clobbered
}
}
and so on, and so forth. There are all kinds of ways to get an invalid pointer value in C. My favourite has got to be the guy who tried to "save" his objects by writing their addresses to a file. Strangely, when he read back those pointer values during a different run of the program, they didn't point to his objects any more. Fancy, that.
But that's just what wild means to me. Since it's not a normative term, it means whatever the person who spoke or wrote it meant it to mean. Ask him or her.
A wild pointer in C is a pointer that has not been initialised prior to its first use.
From Wikipedia:
Wild pointers are created by omitting
necessary initialization prior to
first use. Thus, strictly speaking,
every pointer in programming languages
which do not enforce initialization
begins as a wild pointer.
This most often occurs due to jumping
over the initialization, not by
omitting it. Most compilers are able
to warn about this.
eg
int f(int i)
{
char* dp; //dp is a wild pointer
...
}
It is not s standard term. It is normally used to refer to the pointers pointing to invalid memory location.
int *p;
*p = 0; //P is a wild pointer
Or
int *p = NULL;
{
int a;
p = &a; // as soon as 'a' goes out of scope,'p' is pointing to invalid location
}
*p = 0;
To get a wild (aka dangling) pointer you:
Create an object
Create a pointer to that object
Delete the object
Forget to set the pointer to null
The pointer is now classed as "wild" as it's pointing to an arbitrary piece of memory and using it in this state could cause problems with your program.
A pointer which is not initialized with any address is called as a wild pointer. It may contain any garbage address, so dereferencing a wild pointer is dangerous
A wild pointer is any pointer that is used (particularly as an L_value {ie (*pointer) = x } ) while having a value that is either not correct or no longer correct. It could also be used to describe the using of memory that is not defined as a pointer as a pointer (possibly by having followed a wild pointer or by using outdated structure definitions).
There's no official definition. It's just words that we use when referring to certain pointer errors or the results of those errors.
Wiki
It's a pointer to either uninitialized object or an object with a bad state. using this pointer will cause trouble. the wiki is a good source of explanation.
Wild pointer is a pointer that doesn’t point to either a valid object (of the indicated type, if applicable), or to a distinguished null value, if applicable.
Read more about Wild Pointer here
Wild pointer is a pointer which declaration is present but it has not been defined yet.Means we have declare a pointer -
data_type *ptr; //but not define which address it is containing
*ptr=100//wild pointer does not point to any valid address.so we will get ERROR
printf("ptr:%d",ptr);//we will get:0(in gcc compiler)
a ponter which not have locating any data type varable that varable is call the wild pointer
Uninitialized pointer is called Wild Pointer.
Suppose if you try
int *p; //pointing to any random or unknown location.
*p= 16; /Some unknown memory location is being corrupted.This should never be done./
This can create a great threat to your program. B'Coz because they point to some arbitrary memory location and changing the content of that location may cause a program to crash or behave badly.
#include <stdio.h>
int main(void)
{
int *ptr;
printf("%p", ptr); // Error: uninitialized local variable 'ptr' used
// Output is "0"
}
I'm reading C-FAQ about null pointer. And it says that uninitialized pointer might point to anywhere. Does that mean it points to random location in memory? Also if this statement is true, why does error occur if i try printf("%p",ptr)? Since uninitialized pointer ptr points to some random location, it seems that it must print out this random location!
The contents of an unitialized auto variable (pointer type or otherwise) are indeterminate; in practice, it's whatever was last written to that memory location. The odds that this random bit pattern corresponds to a valid address1 in your program are pretty low; it may even be a trap representation (a bit pattern that does not correspond to a legal value for the type).
Attempting to dereference an invalid pointer value results in undefined behavior; any result is possible. Your code may crash outright, it may run with no apparent issues, it may leave your system in a bad state.
That is, the address of an object or function defined in your program, or a dynamic object allocated with malloc or similar.
I was playing around with pointers the other day and came up with the following code where I explicitly cast an int variable to int * and print out the address of the explicitly casted variable
#include <stdio.h>
int main (void)
{
int d;
int *p1, *p2;
printf("%p\n", p1 = &d);
printf("%p\n", p2 = (int *) d);
return 0;
}
Here's the output:
ffbff71c
ffbff878
My question is what is that second address and what is contained there?
Garbage - you're printing out the value of an uninitialized variable. It's just total coincidence that it looks like your other address; initialize d to get a meaningful answer.
In the second print, you are not printing an address, but a value converted to an address!
In the first assignment, you're taking the address of the variable, which is just some RAM address. In the second assignment, you're converting the variable's value to a pointer. Since the variable is not initialized, that's the garbage value located at that RAM address.
It is just a random address in memory since d is not initialized.
As others have pointed out, you are converting an indeterminate value to a pointer. Performing that conversion, or indeed doing anything with that value other than overwriting it, produces undefined behavior.
If d's value were set prior to the conversion, then it would matter that C explicitly permits integers to be converted to pointers. However, for this case and most others, the standard says:
the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
[C2011, 6.3.2.3/5]
So basically, don't do that unless you know enough to determine reliably for yourself what the result will be with your particular combination of code, C implementation, compile and link options, and platform.
According to this Berkeley course and this Stanford course, assigning an int to a pointer like so should crash my program:
#include<stdio.h>
int main() {
int *p;
*p = 5;
printf("p is %d\n", *p);
return 0;
}
Yet when I compile this on OSX 10.9.2 using GCC {Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)} I get the following output:
Chris at iMac in ~/Source
$ ./a.out
p is 5
How come? I see the reverse question has been asked (Allocating a value to a pointer in c) but this only confuses me further as my program is nearly identical to the code posted in that question.
You are not allocating int to a pointer. If p is a pointer, *p points to its value. You are assigning *p = 5; which is plain integer to integer assignment.
In this case, p is not initialized and may give rise to segmentation fault.
According to this Berkeley course and this Stanford course, allocating an int to a pointer like so should crash my program:
First off let's get your terminology correct. You are not "allocating an int to a pointer". Allocation is the creation of a storage location. An int is a value. A pointer is a value. A pointer may be dereferenced. The result of dereferencing a valid pointer is to produce a storage location. The result of dereferencing an invalid pointer is undefined, and can literally do anything. A value may be assigned to a storage location.
So you have:
int *p;
You have allocated a (short-lived) storage location called p. The value of that storage location is a pointer. Since you did not initialize it to a valid pointer, its value is either a valid pointer or an invalid pointer; which is it? That's up to your compiler to decide. It could always be invalid. It could always be valid. Or it could be left up to chance.
Then you have:
*p = 5;
You dereferenced a pointer to produce a storage location, then you stuck 5 in that storage location. If it was a valid pointer, congratulations, you stuck 5 into a valid storage location. If it was an invalid pointer then you've got undefined behaviour; again, anything could happen.
printf("p is %d\n", *p); // 5!
Apparantly you got lucky and it was a valid storage location this time.
According to this Berkeley course and this Stanford course [this] should crash my program:
Then those courses are wrong, or you are misquoting them or misunderstanding them. That program is permitted to do anything whatsoever. It is permitted to send an email inviting the president of Iran to your movie night, it is permitted to print anything whatsoever, it is permitted to crash. It is not required to do anything, because "permitted to do anything" and "required to do something" are opposites.
My answers: You're lucky!
The fact is, the value you happen to have in p is a valid memory address, that you can actually write to, this is why it works...
Try playing with optimising options (-O3) in your compiler, than you'll get different results...
Your program is not guaranteed to fail, neither is it guaranteed to succeed. You are dereferencing a pointer which could hold any address. It is undefined behaviour.
It's not that it should crash, but it is undefined behavior.
Depending on the system and the runtime circumstances, assigning to a dereferenced and uninitialized pointer can either segfault or continue running "normally," which is to say that it appears work but may have unusual side effects.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
#include <stdio.h>
int j;
int *ptr;
int main(void)
{
j = 13232323;//adress I want to assign
ptr = j;//assign the adress to the pointer
printf("%d",ptr);
}
OUTPUT:13232323
Am I doing wrong as assigning adress directly to a pointer? Pointer is nothing but a variable contains value in the address form, so I constructed an address and then assign it to the pointer,it works as it was supposed to be, except that I can not construct an address containing characters ABCDEF,so,what's the big difference between int and pointer?
EDIT:
This code means nothing but solely for testing purpose
Actually what your trying is out of your eagerness., I agree, I too often do this way.
The Very first thing is if you store 13232323 in a pointer variable, the hex value of it is OXC9E8C3., so really at the time of your assigning the pointer variable (ptr) doesnot know whether really it is a valid address or invalid address. But when you dereference this address with *ptr, then comes the problem. It tries to seek the value in the address.
Then there are 2 cases..
Really if what you assigned is a valid address , then it will return the value. (Practically impossible case)
Mostly your address will be a invalid one, hence program will crash (Segmentation fault).
So, even though your program compiles, runs, until and unless you store a valid address in ptr., ptr has no use.
Your Q: It works as it was surposed to be,except that I can not construct an
address containing characters ABCDEF,so,what's the big difference
between int and pointer? printf("%d",ptr);
I think you are asking, whatever the case, I cannot store ABCDEF, hence ptr works same as int type, so what is the difference between integer and pointer?
Here it is :
You cannot deference an integer value, where as pointer can do it.
Hence it is called as pointer :)
You are seeing only numbers because you are printing the address with %d, trying printing with %x or %p.
Atlast, do you notice the compiler warning, warning: assignment makes pointer from integer without a cast , because ptr = j; in that ptr is of int* type, and j is of int type.
you need to use %x, or you can send *ptr to the printf
printf("%d", *ptr);// if you are using this you need to know what are you pointing at, and that it will be an integer
or
printf("%x", ptr);
as the comments below says, it is always better to use %p instead of %x because %x invoke undefined behaver. also when using %p one should cast his pointer to (void *)
Your code is invalid. C language does not allow this assignment
ptr = j;
Integer values cannot be converted to pointer types without an explicit cast (constant zero being the only exception).
If the code was accepted by your compiler, it simply means that your compiler extends the language beyond its formal bounds. Many compilers do that in one way or another. However, if your compiler accepted this code without issuing a diagnostic message (a warning or an error), then your compiler is seriously broken.
In other words, the behavior of our program has very little (or nothing) to do with C language.
In C you can do most of the type conversion, even the types are totally unrelated. It may cause warning though. make sure that your type conversion make sense.
Syntactically, you are not doing anything wrong here. You can anyways, assign one pointer to another, and since they only contain addresses like the one you assigned here, this is what actually happens during the pointer assignment.
But you should never assign a random address and try to dereference it, because your program doesn't have access to a memory location unless alloted by the machine. You should request the memory from the machine using a function like malloc().
As for differences between pointers and integers, the biggest one is that you can't use a dereference operator (*) on an integer to access the value at the address it contains.
And you can construct addresses using ABCDEF by prefixing your address value with 0X or 0x to signify a hexadecimal notation.
Am I doing wrong as assigning adress directly to a pointer?
Yes, the only integer types that are supposed to work directly with pointers as you do are intptr_t and uintptr_t, if they exist. If they don't exist you are not supposed to do this at all. Even then you would have to use an explicit cast to do the conversion.
Pointer is nothing but a variable contains value in the address
form,so I constructed an adress and then assign it to the pointer,it
works as it was surposed to be,except that I can not construct an
address containing characters ABCDEF,so,what's the big difference
between int and pointer?
No, on some architectures pointers can be more complex beasts than that. Memory can e.g be segmented, so there would be one part of the pointer value that encodes the segment and another that encodes the offset in that segment. Such architectures are rare nowadays, nevertheless this is something that is still permitted by the C standard.
you need ptr to hold the address of j by doing the following
ptr = &j;
ptr hold, equal to, the address of j
and you want to print the content of whats ptr is pointing to by the following
printf("%d",*ptr);
and to get the address of ptr do the following
printf("%x",ptr);
x for the hex representation