When I compile this code :
int main() {
int a = 10;
int *p = &a;
printf("%p",p) // or printf("%p",&a);
return 0;
}
it prints 0022ff38.
Then this code :
int a=10;
int *p =(int *)0x22ff38;
printf("%d",*p); //does not output 10;
should print 10, but it output another thing(2293560).
But when I edit the code, and add a single line :
int main() {
int a = 10;
int *p =(int *)0x22ff38;
printf("%p",&a);
printf("%d",*p); // Now it prints correctly:10
return 0;
}
Every thing is ok!.
Questions:
Why my code does not output a value in first code?
What is usage of this way addressing pointers? is it useful?
Edit :
I have no problem in Linux, because in Linux every time that I run the code, the variable address changes and program output segmentation fault. but in windows address remains the same, and it is expected that manual addressing work in windows.
Compilers are smarter than you think. For example, given this code:
int main() {
int a=10;
int *p =(int *)0x22ff38;
printf("%d",*p);
}
The compiler is going to see that a is never even used. So it will never bother to actually allocate any memory for it.
If you add a printf("%d", a), the compiler might only put a in a register and never in memory.
Fundamentally, you can't assume that two programs will put variables in the same place in memory.
Related
Trying to access/print function member using following snippet
void func()
{
int i=4;
}
int *k = func + 4;
int main()
{
printf("%x\n", func);
printf("%x\n", k);
printf("%d\n", *(int *)k);
return 0;
}
and looking to get value of i through last printf statement but wondering if it is possible this way ?
output of program is:
400526
40052a
83641799
First of all, no, it's not possible at all to do in any reliable way.
And this idea does not make sense either. The variable i will typically not be exist nearby the function code. Also, it will typically be created at different places on different calls.
However, something that's possible is this:
int *func()
{
static int i=4;
return &i;
}
int *k;
int main()
{
k = func();
That's perfectly valid, even if the usefulness could be discussed.
But you will never be able to access it via an offset to the function pointer. At least not in a legal way.
This question already has answers here:
What happens when a variable goes out of scope?
(3 answers)
Closed 6 years ago.
I am studying the working of an automatic variable. I know that it is only accessible inside the block or function in which it is declared and its lifetime is within that same function or block. So the following piece of code I am trying to check.
/Declaration of header files/
void testfn(void);
int *p;
int main(void)
{
testfn();
print("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
The output is - 444
I am wondering that when the testfn(); exits,the variable x will be destroyed. Then how in main function the pointer (*p) prints 444.
How this works...or if I am missing something.
Please clarify my doubt.
Thanks
It is coincidence that the original value still remains. With another compiler, or with another compilation configuration, it could take any other value or the program could just crash.
If between the testfn and printf functions you call any other function that does something with its local variables, you might see that the 444 value is not obtained anymore. But this is just, again, coincidence.
p points to the stack where x was stored. If the memory location hasn't been used for something else you will most likely get 444.
Try to insert another function call before printing p and see what happens:
#include <stdio.h>
#include <math.h>
void foo() {
int y=123;
}
void testfn(void);
int *p;
int main(void)
{
testfn();
foo();
printf("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
On my machine, the output is now:
123
Since the code results in undefined behaviour, the result could be different if I try this on another platform. But you can see that undefined behaviour can lead to strange bugs.
The memory location that was previously reserved for variable x is not overwritten yet. But it may be at any time. That's why your code leads to undefined behaviour.
In the following example, the memory location that was previously reserved for variable x will be overwritten by the value that is assigned to the variable y. Since the pointer p still points to that location, *p will evaluate to this new value:
#include <stdio.h>
int *p;
void test1(void) {
int x = 444;
p = &x;
}
void test2() {
int y = 15;
}
int main(void) {
test1();
test2();
printf("%d\n",*p);
return 0;
}
The fact that the value still remains is completly coincidental (not guaranteed) because nothing has overwritten it yet.
You can not count on this, it may fail, may print garbage or may crash your program or pc even.
Don't use this, it is considered undefined behavior.
#include <stdio.h>
void interrupt();
int main() {
int n = 8;
char c = 'Z';
interrupt();
printf("%d%c\n", n, c);
}
void interrupt() {
printf("Run normally\n");
//ADD CODE...
}
As it stands, this function will output "8Z" regardless of what the interrupt() method does. I am attempting to modify it such that it prints "3Y" without changing anything in the original main function, and only using the interrupt() function (not allowed to pass arguments!). I am allowed to use variables in the interrupt() function, but I am confused to as how you obtain the addresses of 'n' and 'c' without making a global variable, which would defeat the purpose of this question. Since the address of the stack changes every time this runs, there doesn't seem to be a way to do pointer arithmetic (which is what I need to do), and therefore I'm a bit confused and stuck.
Disclaimer: Don't attempt to use this in production code
I took this as a puzzle and proceeded to solve it. You said you are not allowed to modify main. I took the liberty of modifying main slightly -- to print the addresses of n and c.
int main()
{
int n = 8;
char c = 'Z';
printf("%p %p\n", &n, &c);
interrupt();
printf("%d%c\n", n, c);
}
I also modified interrupt a little bit, also to print the values of an address.
void interrupt() {
int i = 10;
char* np = (char*)&i;
char* cp = (char*)&i;
printf("%p %p\n", np, cp);
printf("%p\n", &i);
}
When I ran the program, I got the following output:
0x22cb0c 0x22cb0b
0x22cabc 0x22cabc
0x22cabc
8Z
From the output, I am able to compute the offset between &n in main and &i in interrupt, and the offset between &c in main and &i in interrupt. Now I can manipulate the offset to make np and cp in interrupt to point to n and c in main.
void interrupt() {
int i = 10;
char* np = (char*)&i;
char* cp = (char*)&i;
np += (0x22cb0c - 0x22cabc);
cp += (0x22cb0b - 0x22cabc);
*(int*)np = 3;
*cp = 'Y';
printf("%p %p\n", np, cp);
printf("%p\n", &i);
}
With the changes to interrupt, I get the following output:
0x22cb0c 0x22cb0b
0x22cb0c 0x22cb0b
0x22cabc
3Y
Mission accomplished by changing main a little bit. If you are not allowed to change it at all, you'll have to use a different program to compute the offsets.
By what #Alex Skalozub said, you can get the stack offset and modify the local variables in the calling function.
You can:
1. Study the compiler and OS manual to calculate the stack offset.
Or
2. Write a little function to get it at run-time. Like below.
int get_stack_offset(void)
{
long dummy1;
return dummy_call(&dummy1) + sizeof(dummy1);
}
int dummy_call(int address)
{
long dummy2;
return &dummy2 - address;
}
Then you can just
void interrupt() {
printf("Run normally\n");
int stack_offset = get_stack_offset();
char* c_address = (char*) (&stack_offset - stack_offset);
int* n_address = (int*) (c_address - sizeof(char));
// Then, modify them
*c_address = 'Y';
*n_address = 3;
// Other
// ...
}
*Assuming the stack is increasing. When it is decreasing you need reverse the +/- operator.
*I don't consider about alignment, which maybe you need to.
*And here is a great explanation you can reference.
Does stack grow upward or downward?
#include<stdio.h>
int main(){
int *j;
void fun(int**);
fun(&j);
return 0;
}
void fun(int **k){
int a=10;
/* Add a statement here */
}
In the following program add a statement in the function fun() such that address of a gets stored in j? Can someone please explain this whole program. I am not able to get this meaning of **.
All you want is: *k = &a;
The ** thing means it is a pointer to a pointer. I think the following diagram will make it clear. Open the image in a new tab to see it clearly.
Read more here.
I have a piece of code where I am trying to return the square of the value pointed to by *ptr.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
main()
{
int a=8,t;
t=square(&a);
printf("%d",t);
}
Its working fine for me but author of this code said it might not work because of following reason:
Because it's possible for the value of *ptr to change unexpectedly, it is possible for a and b to be different. Consequently, this code could return a number that is not a square!. The correct way to do is
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
I really wanted to know why he said like that?
The idea of the volatile keyword is exactly to indicate to the compiler that a variable marked as such can change in unexpected ways during the program execution.
However, that does not make it a source of "random numbers" - it just advises the compiler - what is responsible for actually changing the variable contents should be another process, thread, some hardware interrupt - anything that would write to the process memory but not inlined in the function where the volatile declaration finds itself. In "older times" (compilers with less magic) everything it did was preventing the compiler from caching the variable value in one of the CPU registers. I have no idea on the optimisations/de-optimistions strategies triggered by it by modern compilers - but it will at least do that.
In the absense of any such external factor, a "volatile" variable is just like any other. Actually - it is just like any other variable - as variables not marked as volatile can also be changed by the same external causes (but the compiled C code would not be prepared for that in this case, which might lead to incorrect values being used).
Since the question has an accepted and correct answer, I will be brief: here is a short program that you can run to see the incorrect behavior happening for yourself.
#include <pthread.h>
#include <math.h>
#include <stdio.h>
int square(volatile int *p) {
int a = *p;
int b = *p;
return a*b;
}
volatile int done;
void* call_square(void* ptr) {
int *p = (int*)ptr;
int i = 0;
while (++i != 2000000000) {
int res = square(p);
int root = sqrt(res);
if (root*root != res) {
printf("square() returned %d after %d successful calls\n", res, i);
break;
}
}
done = 1;
}
int main() {
pthread_t thread;
int num = 0, i = 0;
done = 0;
int ret = pthread_create(&thread, NULL, call_square, (void*)&num);
while (!done) {
num = i++;
i %= 100;
}
return 0;
}
The main() function spawns a thread, and modifies the data being squared in a loop concurrently with another loop calling the square with a volatile pointer. Relatively speaking, it does not fail often, but it does so very reliably in less than a second:
square() returned 1353 after 5705 successful calls <<== 1353 = 33*41
square() returned 340 after 314 successful calls <<== 340 = 17*20
square() returned 1023 after 5566 successful calls <<== 1023 = 31*33
First understand what's volatile: Why is volatile needed in C?
and then, try to find answer by yourself.
It's a game of volatile and hardware world. :-)
Read answer given by Chris Jester-Young:
volatile tells the compiler that your variable may be changed by other means, than the code that is accessing it. e.g., it may be a I/O-mapped memory location. If this is not specified in such cases, some variable accesses can be optimised, e.g., its contents can be held in a register, and the memory location not read back in again.
If there is more than one thread, the value the pointer points to might change inbetween statement "a = *ptr" and statement "b = *ptr". Also: you want the square of a value, why put it into two variables?
In the code you present then there is no way for the variable a that is defined in your main to be modified whilst square is running.
However, consider a multi-threaded program. Suppose that another thread modified the value to your your pointer refers. And suppose that this modification took place after you had assigned a, but before you had assigned b, in the function sqaure.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//the other thread writes to *ptr now
b = *ptr;
return a * b;
}
In this scenario, a and b would have different values.
The author is correct (if *ptr will be changed by other threads)
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//between this two assignments *ptr can change. So it is dangerous to do so. His way is safer
b = *ptr;
return a * b;
}
Because the value of the pointer *ptr might change between the first affection and the second one.
I don't think the value of *ptr can change in this code barring an extremely unusual (and non-standards-compliant) runtime environment.
We're looking at the entirety of main() here and it's not starting up other threads. The variable a, whose address we are taking, is a local in main(), and main() doesn't inform any other function of that variable's address.
If you added the line mysterious_external_function(&a); before the t=square(&a) line, then yes, mysterious_external_function could start a thread and diddle the a variable asynchronously. But there's no such line, so as written square() always returns a square.
(Was the OP a troll post, by the way?)
I see some answers with *ptr can be changed by other threads. But this cannot happen since *ptr is not a static data variable. Its a parameter variable and local and parameter variables being hold inside stack. Each thread has its own stack section and if *ptr has been changed by another thread, it should not effect the current thread's.
One reason why the result might not give the square can be an HW interrupt might happen before assigning b = *ptr; operation as indicated below:
int square(volatile int *ptr) {
int a,b;
a = *ptr; //assuming a is being kept inside CPU registers.
//an HW interrupt might occur here and change the value inside the register which keeps the value of integer "a"
b = *ptr;
return a * b;
}