This question already has answers here:
pointer default value .?
(4 answers)
Closed 4 years ago.
How are pointers in C initialized? It seems like previous declarations change how they are initialized.
Consider the following example:
int *a;
printf("a: %p\n", (void*)a);
This code snippet results in
a: (nil)
So one could think that variables at function start are initialized with null, but if I execute this code:
int *a;
for(int i = 0; i < 1; i++){
int *b;
printf("a: %p\n", (void*)a);
printf("b: %p", (void*)b);
}
This is the result:
a: 0x7ffff3bb2e40
b: (nil)
How can I determine how the variables are initialized?
If a pointer is defined at file scope, it is initialized to NULL.
If it is defined at block scope, the pointer is uninitialized, so it could have any random value, including NULL.
Given that you are not assigning an initial value, it depends on what there is on the memory beforehand. So there are two possibilities
Garbage. Indeterminate values which come from a previous execution or status, etc...this l yields an undefined behaviour.
Initialization during startup. It is quite common to initialize to zero some segments of memory such us the bss segment during the startup (before main()). In this case, you are not initializating the variable, you are initializating the bunch of memory in which the variable is allocated, anyway, this won't yield an undefined behaviour.
Edited for accuracy due to M.M 's comment.
How are pointers in C initialized?
In C, local pointers (in automatic variables) are not initialized unless you code explicitly their initialization. You have an undefined behavior. Be scared.
The only pointers which are implicitly initialized are those in global or static variables (so called file scope variables). In practice, such pointers are initialized to all zero bits, which usually means the NULL pointer.
In practice, with a modern compiler like a recent GCC, you should enable all warnings and debug info (e.g. compile with gcc -Wall -Wextra -g). Then you'll get warnings. Improve your code to have none.
Related
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 12 months ago.
In an Microprocessor it is said that the local variables are stored in stack. In my case if func1() is called by main function then the local variable (int a = 12;)will be created in stack. Once the Called Function is executed the and return back to main function the stack memory will be deleted. So the pointer address still holds (*b) the value 12. At stack if this 'a = 12' is deleted then 'b' should be a dangling pointer no?? Can anyone explain this ? If you have detailed explanation on what happens in memory when this code is being executed it would be helpful.
#include <stdio.h>
int* func1(void);
int main()
{
int* b = func1();
printf("%d\n",*b);
}
int* func1(void)
{
int a = 12;
int* b = &a;
return b;
}
The pointer is dangling. The memory may still hold the previous value, but dereferencing the pointer invokes undefined behaviour.
GCC will give you a warning about this, if you pass -Wall option.
From the C standard (6.2.4):
The lifetime of an object is the portion of program execution during
which storage is guaranteed to be reserved for it. An object exists,
has a constant address,25) and retains its last-stored value
throughout its lifetime.26) If an object is referred to outside of its
lifetime, the behavior is undefined. The value of a pointer becomes
indeterminate when the object it points to reaches the end of its
lifetime.
There are multiple layers here.
First, is the C programming language. It is a language. You say stuff in it and it has meaning. There are sentences that have meaning, but you can also construct grammatically valid sentences that are gibberish.
The code you posted, grammatically valid, is gibberish. The object a inside func1 stops existing when the function returns. *b tries to access an object that does not exists anymore. It is not defined what should happen when you access an object after its lifetime ended. You can read about undefined behavior.
Memory exists. It's not like it is disintegrated when a function returns. It's not like RAM chips are falling out of your PC. They are still there.
So your compiler will produce some machine instructions. These machine instructions will execute. Depending solely on your compiler decisions (the code is undefined behavior, compiler can do what it wants) the actual code can behavior in any way the compiler decides to. But, most probably, *b will generate machine instructions that will read the memory region where object a resided. That memory region may still hold the value 12 or it may have been overwritten somewhere between func1 returning and calling printf, resulting in reading some other value.
At stack if this 'a = 12' is deleted then 'b' should be a dangling pointer no?
Yes.
what happens in memory when this code
This depends on the actual machine instructions generated by the compiler. Compile your code and inspect the assembly.
Strictly speaking, the behaviour is undefined, but repeat the printf or otherwise inspect (in your debugger for example) *b after the printf. It is likely that it will no longer be 12.
It is not accurate to say that the stack memory is "deleted". Rather the stack pointer is restored to the address it had before the call was invoked. The memory is otherwise untouched but becomes available for use by subsequent calls (or for passing arguments to such calls), so after calling printf it is likely to have been reused and modified.
So yes, the pointer is "dangling" since it points to memory that is no longer "valid" in the sense that it does not belong to the context in which the pointer exists.
Happy new year everyone.
I am studying C language. I had a question when some code run about pointer.
#include <stdio.h>
int * b() {
int a = 8;
int *p = &a;
printf("the addr of a in b: %p\n", p); the addr of a in b: 0x7ffccfcba984
return p;
}
int main () {
int *c = b();
printf("the addr of a in main: %p\n", c); // the addr of a in main: 0x7ffccfcba984
printf("The value of ptr is : %d\n", *c ); // 8
return 0;
}
Can you feel something odd in this code?
I learned that a variables declared inside a function is deallocated at the end of the function.
However, I can still access variables outside the function
like above code when trying to access the address of "a" variable. If the deallocation is true, int a should be deallocated at the end of the b function. It is like a free is not used after variables is declared.
Is there some knowledge I am missing about deallocation?
Could you tell me why I can still access it?
Once you leave a function variables "fall out of scope" meaning they are no longer valid.
Using the address of an out of scope variable breaks that boundary and leads to undefined behaviour, as in, it's not valid to do. The &a pointer is effectively invalidated when you exit that function. If you use it then the program may behave erratically, might crash, or might work fine. It's not defined what happens.
In this trivial example you're not going to get the same behaviour as in a real program. Make another function call to a function that exercises the stack and you'll likely see some problems since the stack is being re-used.
Local variables aren't "allocated" per-se, they are simply scoped, and when that scope is exited they are invalidated.
In something like C++ there may be a deallocation process when things fall out of scope, as that language can define destructors and such, but that's not the same as C. In C they just cease to exist.
I learned that a variables declared inside a function is deallocated at the end of the function.
If the deallocation is true, int a should be deallocated at the end of the b function.
Yes. You are not wrong.
A variable will be destructured when it goes out of its scope. Although you use a pointer variable to save a pointer to that variable, accessing it through that pointer is actually an undefined behavior.
Yes, you can access it and see the results you expect because of luck or environment, but it may still cause a crash, unexpected results, etc. Because this behavior is undefined and wrong.
Do C pointer (always) start with a valid address memory? For example If I have the following piece of code:
int *p;
*p = 5;
printf("%i",*p); //shows 5
Why does this piece of code work? According to books (that I read), they say a pointer always needs a valid address memory and give the following and similar example:
int *p;
int v = 5;
p = &v;
printf("%i",*p); //shows 5
Do C pointer (always) start with a valid address memory?
No.
Why does this code work?
The code invokes undefined behavior. If it appears to work on your particular system with your particular compiler options, that's merely a coincidence.
No. Uninitialized local variables have indeterminate values and using them in expressions where they get evaluated cause undefined behavior.
The behaviour is undefined. A C compiler can optimize the pointer access away, noting that in fact the p is not used, only the object *p, and replace the *p with q and effectively produce the program that corresponds to this source code:
#include <stdio.h>
int main(void) {
int q = 5;
printf("%i", q); //shows 5
}
Such is the case when I compile the program with GCC 7.3.0 and -O3 switch - no crash. I get a crash if I compile it without optimization. Both programs are standard-conforming interpretations of the code, namely that dereferencing a pointer that does not point to a valid object has undefined behaviour.
No.
On older time, it was common to initialize pointer to selected memory addresses (e.g. linked to hardware).
char *start_memory buffer = (char *)0xffffb000;
Compiler has no way to find if this is a valid address. This involve a cast, so it is cheating.
Consider
static int *p;
p will have the value of NULL, which doesn't point to a valid address (Linux, but on Kernel, it invalidate such address, other OS could use memory on &NULL to store some data.
But you may also create initialized variables, so with undefined initial values (which probably it is wrong).
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
How to access a local variable from a different function using pointers?
(10 answers)
Closed 4 years ago.
#include <stdio.h>
int* function1(void);
int main()
{
int x = 10;
int *p = function1();
printf("%d\n", *p);
printf("%d\n", p);
}
int* function1(void)
{
int z;
z = 20;
z++;
return &z;
}
Variable 'z' is local to the 'function1', and is not alive after the
'function1' is terminated.
Now to access the value at the memory space of the variable 'z', its
address is returned by the function.
So, even after the termination, will the memory space of the variable
'z' will still be reserved, as the pointer accesses the variable?, in such case what will be the properties of the memory space?
Or What if some-other variable is allocated with the same memory space
of variable 'z'?
Note: GCC compiler of code blocks has compiled the program successfully, without any error and warning.
In general what you do is undefined.
However, on Intel architectures z is on the stack and after return, if you don't call any other function the value will probably still be available because the memory has not yet been reused. As soon as you call another function, the memory will probably be overwritten and so will contain garbage for you.
In general: Don't do this!
The variable z does no longer exist after the function function1 finishes it's execution. In function main you are trying to reference a memory address which has been deallocated after the function's call. This will cause undefined behavior.
When the function call happens, all your local variables will be in stack. During function call, the stack variables can be modified. When the function call returns, the stack pointer is decremented’
Hence, you will be accessing something which is not guaranteed in any way. In programming languages, this is addressed as a case of undefined behaviour, since you are overriding the rules of programming language.
In this case of function, given that you stack frame is still active and not modified by any other code, you might get the same value that you wrote to that address.
But is not guaranteed in anyway and dont assume anything not guaranteed.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
#include<stdio.h>
int* add(int *a, int *b){
int c = *a + *b ;
return &c;
}
int main(void) {
int a=3,b=2 ;
int *ptr = add(&a,&b); // doubt in this line as it returns 5
printf("%d",*ptr);
}
I have doubt in the line commented.
I am using Codeblocks IDE(GNU gcc compiler), and I was wondering that if the *ptr in my main is pointing to the address of c in the add function, then it should print garbage as after the function `add completes its execution, it's popped from the stack, and the memory should be deallocated for it in the stack . So technically, it should be pointing to garbage. Then how is it printing the correct value.
You have undefined behavior, as you are returning the address of a function-local variable. A good compiler with warnings enabled would tell you this.
When you have undefined behavior you don't get to complain about the results. There is no need to wonder why it gives you the "correct" result because it does not--it gives you some number which may or may not be correct depending on any number of factors you don't control.
I think this is undefined behavior. On my system this example crashed with a segmentation fault. When something is deallocated, it is possible that the pointer to that memory location is simply moved without zeroing out the memory.