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.
Related
Background info: My program involves creating a hash table and one of my functions is free_hash(struct hash_table *table).
struct hash_table *table points to an array of struct hash_entry pointers. To test my free_hash function in main I have a void *test_free = what. the declaration and initialization for what is hash_table *what = new_hash(array_size).
this is struct hash_table *new_hash() it returns a function that returns a pointer to a new initialized struct hash_table.
My question: After freeing what, eg.free_hash(what), what happens to test_free. What is the address of it/the value of what it is pointing at. And is there any other way I can make sure that what has been destructed/freed.
test_free and what are pointers. The value they have is basically an address. And you assigned the same address to both of them. Nothing happens to either variable once you free that to which they point.
Once you do, the pointers are deemed to be indeterminate, so it becomes undefined behaviour to deference either one. But there's nothing in either variable that indicates this. The onus is on the programmer to ensure no attempts is made to access a freed structure.
As for checking if everything was properly freed, there's -fsanitize=address, valgrind, etc.
C 2018 6.2.4 2 says “… The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.” When you release memory with free, the lifetime of any objects in it end, so any pointers to this memory become indeterminate. “Indeterminate” means the pointer value is not even fixed; it may act as if it has a different value each time it is used.
This rule exists because there have been C implementations in which maintaining pointers required auxiliary information associated with the allocated memory. So the “value” of a pointer was not represented just by the bits directly in the memory used for the pointer object itself. Once the memory, and its auxiliary information, are released, it might no longer be possible to interpret the value of the pointer correctly.
In most modern C implementations, addresses are implemented simply as numbers in a “flat” address space. In this case, no auxiliary information is needed to interpret the value of a pointer or to work with it as by adding offsets to it. However, because the rule exists, optimizers in compilers may treat any pointer to freed memory as indeterminate.
For example, in this code:
void *x;
free(p);
if (SomeTest)
x = p;
else
x = q;
printf("%p\n", x);
the compiler is allowed to optimize this to:
void *x;
free(p);
x = q;
printf("%p\n", x);
even if SomeTest is true. That is the fact that p is indeterminate after free means it is allowed to have any value, so it could have the value of q, so the if statement would just be:
if (SomeTest)
x = q;
else
x = q;
which of course can be optimized to x = q;.
In short, once you release memory, the C standard does not give you any assurance your program will behave as if a pointer to that memory has any particular value. It may act as if the pointer has a different value each time the program uses it.
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.
I am learning now C, and these days I am studying pointers and I just come with a question!
int *ptr; //declare the ptr
ptr = &var; //init the ptr with the address of the variable var
with these lines, I created a pointer and I linked the ptr with a variable. My question is this, when I declare a pointer int *ptr; and I don't initialize it with an address, this pointer where it points?
In C, variables are generally not initialized unless you specifically say so:
int a; // not initialized
int b = 1; // initialized
int arr[10]; // not initialized
int brr[4] = { 1 }; // initialized as { 1, 0, 0, 0 }
void * p; // not initialized
void * q = &a; // initialized
(There are exceptions for variables with static or thread-local storage, which are always zero-initialized.)
It is not allowed to try and get at the value of an uninitialized variable. The only thing you can do with an uninitialized variable is assign to it, which does not access its current value, but only assigns a new value to it. Before initialization or assignment, the current value of a variable is "indeterminate" and you must not attempt to access it. Doing so results in undefined behaviour.
This is true for all variables, but in particular it applies to your pointer variable. It simply has no meaningful value until you assign one.
void * p; // not initialized
if (p) { /*...*/ } // undefined behaviour!
printf("%p\n", p); // undefined behaviour!
p = &a; // now p has a well-defined value
The technical term for the action that is causing undefined behaviour is the so-called "lvalue conversion". That is the moment in which you take a named variable (an "lvalue") and use its content. E.g. C11, 6.3.2.1/2 says:
If the lvalue designates an object of automatic storage duration [...] and that object
is uninitialized (not declared with an initializer and no assignment to it has been
performed prior to use), the behavior is undefined.
It is just like any other uninitialized local variable -- it is undefined where it points or what value it contains, and you are not allowed to use it (e.g., dereference it) until it is initialized. As stated in #WhozCraig's comment, almost all other operations are forbidden as well (using the pointer's value at all, including arithmetic and comparisons). Uninitialized non-pointer variables (even those with simple types such as ints) cannot be used for any operations that access their values, either.
Actually, as it has been stated in almost all answers so far, the pointer's value is unknown and consists of the contents of the memory at that location when it was allocated.
Contrary to what some answers state though, noone and nothing is going to forbid you dereferencing it, or doing any kind of operation with this pointer.
As a result, using such a pointer will produce any kind of unpredictable results. It is not only best practice but a requirement for producing less buggy code, to initialize a pointer on declaration to something, even if that something is, simply, NULL.
It points to a random memory location. Dereferencing such a pointer usually leads to a segfault.
In this case, it will point anywhere. You don't know. The contents of the pointer will be whatever was at the memory location before. So this is very dangerous and should be avoided. You should always init a pointer with NULL, then it will point to "nothing" in a defined way.
Like any other non-static variable in C, it's not initialized automatically. It contains whatever junk data was in the memory slot, and so deferencing it before assigning a proper value to it is likely to be a bad idea.
The follow program declares a pointer then again a new pointer to hold address of previous pointer variable.. How much can I use nested pointer variable to hold memory address
is there any limit?
#include <stdio.h>
#include <conio.h>
void main()
{
int x=2,y=5;
int *ptr;
int **sptr;
int ***ssptr;
ptr = &x; // address of x
*ptr = 0;
sptr = &ptr;
ssptr = & sptr;
printf(" address is ip = %u %u %u",ptr,sptr,ssptr);
_getch();
}
There is no limit. A pointer is a chunk of memory (typically one word) whose contents are an address. A pointer to a pointer is also a word whose contents are an address, but it just so happens that the contents at that address is another address. There is nothing particularly special about a pointer to a pointer (to a pointer to a pointer... etc., ad nauseum).
There is no limit. You can even make a pointer that points at itself, which is infinitely recursive:
void *p = &p;
As far as I know, there shouldn't be any limit except for system memory restrictions (in theory). This would depend on the compiler used though.
There is not a limit in the language itself. The purpose of a pointer variable is to store an address. It is possible to store a pointer which points to an address, which points to an address, ..., which points to an address.
However, the more you use these types of nested pointers, the less understandable your code will be.
No there is no limit because they are all just pointers to something, and the thing they point to just happens to be another pointer.
Are you trying to do something practical?
Todd.
The only language I could find that suggests a limit is the following:
5.2.4.1 Translation limits
1 The implementation shall be able to translate and execute at least one program that
contains at least one instance of every one of the following limits:13)
...
— 12 pointer, array, and function declarators (in any combinations) modifying an
arithmetic, structure, union, or incomplete type in a declaration
...
— 4095 characters in a logical source line
...
Actually, memcpy works just fine when I use pointers to characters, but stops working when I use pointers to pointers to characters.
Can somebody please help me understand why memcpy fails here, or better yet, how I could have figured it out myself. I am finding it very difficult to understand the problems arising in my c/c++ code.
char *pc = "abcd";
char **ppc = &pc;
char **ppc2 = &pc;
setStaticAndDynamicPointers(ppc, ppc2);
char c;
c = (*ppc)[1];
assert(c == 'b'); // assertion doesn't fail.
memcpy(&c,&(*ppc[1]),1);
if(c!='b')
puts("memcpy didn't work."); // this gets printed out.
c = (*ppc2)[3];
assert(c=='d'); // assertion doesn't fail.
memcpy(&c, &(*ppc2[3]), 1);
if(c != 'd')
puts("memcpy didn't work again.");
memcpy(&c, pc, 1);
assert(c == 'a'); // assertion doesn't fail, even though used memcpy
void setStaticAndDynamicPointers(char **charIn, char **charIn2)
{
// sets the first arg to a pointer to static memory.
// sets the second arg to a pointer to dynamic memory.
char stat[5];
memcpy(stat, "abcd", 5);
*charIn = stat;
char *dyn = new char[5];
memcpy(dyn, "abcd", 5);
*charIn2 = dyn;
}
your comment implies that char stat[5] should be static, but it isn't. As a result charIn points to a block that is allocated on the stack, and when you return from the function, it is out of scope. Did you mean static char stat[5]?
char stat[5];
is a stack variable which goes out of scope, it's not // sets the first arg to a pointer to static memory.. You need to malloc/new some memory that gets the abcd put into it. Like you do for charIn2
Just like what Preet said, I don't think the problem is with memcpy. In your function "setStaticAndDynamicPointers", you are setting a pointer to an automatic variable created on the stack of that function call. By the time the function exits, the memory pointed to by "stat" variable will no longer exist. As a result, the first argument **charIn will point to something that's non-existent. Perhaps you can read in greater detail about stack frame (or activation record) here: link text
You have effectively created a dangling pointer to a stack variable in that code. If you want to test copying values into a stack var, make sure it's created in the caller function, not within the called function.
In addition to the definition of 'stat', the main problem in my eyes is that *ppc[3] is not the same as (*ppc)[3]. What you want is the latter (the fourth character from the string pointed to by ppc), but in your memcpy()s you use the former, the first character of the fourth string in the "string array" ppc (obviously ppc is not an array of char*, but you force the compiler to treat it as such).
When debugging such problems, I usually find it helpful to print the memory addresses and contents involved.
Note that the parenthesis in the expressions in your assignment statements are in different locations from the parenthesis in the memcpy expressions. So its not too suprising that they do different things.
When dealing with pointers, you have to keep the following two points firmly in the front of your mind:
#1 The pointer itself is separate from the data it points to. The pointer is just a number. The number tells us where, in memory, we can find the beginning of some other chunk of data. A pointer can be used to access the data it points to, but we can also manipulate the value of the pointer itself. When we increase (or decrease) the value of the pointer itself, we are moving the "destination" of the pointer forward (or backward) from the spot it originally pointed to. This brings us to the second point...
#2 Every pointer variable has a type that indicates what kind of data is being pointed to. A char * points to a char; a int * points to an int; and so on. A pointer can even point to another pointer (char **). The type is important, because when the compiler applies arithmetic operations to a pointer value, it automatically accounts for the size of the data type being pointed to. This allows us to deal with arrays using simple pointer arithmetic:
int *ip = {1,2,3,4};
assert( *ip == 1 ); // true
ip += 2; // adds 4-bytes to the original value of ip
// (2*sizeof(int)) => (2*2) => (4 bytes)
assert(*ip == 3); // true
This works because the array is just a list of identical elements (in this case ints), laid out sequentially in a single contiguous block of memory. The pointer starts out pointing to the first element in the array. Pointer arithmetic then allows us to advance the pointer through the array, element-by-element. This works for pointers of any type (except arithmetic is not allowed on void *).
In fact, this is exactly how the compiler translates the use of the array indexer operator []. It is literally shorthand for a pointer addition with a dereference operator.
assert( ip[2] == *(ip+2) ); // true
So, How is all this related to your question?
Here's your setup...
char *pc = "abcd";
char **ppc = &pc;
char **ppc2 = &pc;
for now, I've simplified by removing the call to setStaticAndDynamicPointers. (There's a problem in that function too—so please see #Nim's answer, and my comment there, for additional details about the function).
char c;
c = (*ppc)[1];
assert(c == 'b'); // assertion doesn't fail.
This works, because (*ppc) says "give me whatever ppc points to". That's the equivalent of, ppc[0]. It's all perfectly valid.
memcpy(&c,&(*ppc[1]),1);
if(c!='b')
puts("memcpy didn't work."); // this gets printed out.
The problematic part —as others have pointed out— is &(*ppc[1]), which taken literally means "give me a pointer to whatever ppc[1] points to."
First of all, let's simplify... operator precedence says that: &(*ppc[1]) is the same as &*ppc[1]. Then & and * are inverses and cancel each other out. So &(*ppc[1]) simplifies to ppc[1].
Now, given the above discussion, we're now equipped to understand why this doesn't work: In short, we're treating ppc as though it points to an array of pointers, when in fact it only points to a single pointer.
When the compiler encounters ppc[1], it applies the pointer arithmetic described above, and comes up with a pointer to the memory that immediately follows the variable pc -- whatever that memory may contain. (The behavior here is always undefined).
So the problem isn't with memcopy() at all. Your call to memcpy(&c,&(*ppc[1]),1) is dutifully copying 1-byte (as requested) from the memory that's pointed to by the bogus pointer ppc[1], and writing it into the character variable c.
As others have pointed out, you can fix this by moving your parenthesis around:
memcpy(&c,&((*ppc)[1]),1)
I hope the explanation was helpful. Good luck!
Although the previous answers raise valid points, I think the other thing you need to look at is your operator precedence rules when you memcpy:
memcpy(&c, &(*ppc2[3]), 1);
What happens here? It might not be what you're intending. The array notation takes higher precedence than the dereference operator, so you first attempt perform pointer arithmetic equivalent to ppc2++. You then dereference that value and pass the address into memcpy. This is not the same as (*ppc2)[1]. The result on my machine is an access violation error (XP/VS2005), but in general this is undefined behaviour. However, if you dereference the same way you did previously:
memcpy(&c, &((*ppc2)[3]), 1);
Then that access violation goes away and I get proper results.