tags:

views:

162

answers:

4

Hi all,

Recently while surfing some C++ blogs, I came across a small C teaser program in one of them.

#include<stdio.h>

int find_addr()
{
/*fill your code here*/
}

int main()
{
int i,j;
clrscr();
find_addr();
return 0;
}

The question is to find the address of variables i & j without touching the main function. I haven't been able to figure it out yet. Feels awful that I couldn't even solve this minor question :((.

EDIT:

The above program had lot of non-standard statements like the use of inclusion of conio.h anbd other non standard headers and its functions , getch() and other statements, I edited it in a hurry and forgot to omit void from void main(), apologies for that.

EDIT2: I have given my one vote to close this thread since I perceive through the responses posted here that there are non-standard issues related to the question.

+7  A: 

I think I found where you read the puzzles. Most of the programs use typeless main(), or worse, void main(). They assume a lot of system- and/or compiler-specific things. The programs on the page are not very good quality, and make for a bad tutorial. Please stay away from it.

For example, this is the first program:

what is the output? Definitely the output is not what you think! so think more..

main()
{
    int i = 300;
    char *ptr = &i;
    *++ptr = 2;
    printf("%d",i);
    getch();
}

Third program:

what is the output of the following code if array name starts with 65486?

void main()
{
    int num[] = {10,11,12,13};
    printf("%u %u",num,&num);
}

I could go on, but there is no need really. As I said, stay away from this page!

Alok
Seems like the person who wrote these programs wanted to maximize `sizeof(undefined behavior) / sizeof(code)`. :-)
Alok
The first program you have mentioned for output just changes the second integer byte and hence the whole integer variable changes. For example on a linux system where int is 4 bytes, the second byte is changed to integer 2 and when the whole integer is displayed the interpretation of the 4 bytes changes. Ofcourse the compiler gave out warnings. But just for the fun of what happens behind the scenes I tried to work it out.
rocknroll
@rocknroll: please do yourself a favor and actually read the answers to your post. What you are trying to do is non-standard, and trying to understand C or computers this way is the wrong way to go about it. The reason I posted those two questions above is not because I want you to answer them, but because they are really badly written programs. Compile them with `gcc -ansi -pedantic -W -Wall` to see what I mean.
Alok
@Alok, I got your point earlier very well, it was out of curiosity I tried to work it out, that's it. And I got everybody's point here that it is non-standard and given my vote to close this thread.
rocknroll
@rocknroll: nice! and thanks for the comments.
Alok
+4  A: 

I think it could look like the following, but it is not conformant way and you shouldn't use it in practice.

int find_addr()
{
  int t;
  int* i_addr = &t - <some platform&compiler&whatever specific constant>;
  int* j_addr = &t - <some platform&compiler&whatever specific constant>;
}

The idea is that i and j are placed on the stack and you could find address of stack by using address of one more variable on the stack.

You should note that sometimes it is impossible to find addresses of i and j because compiler will not allocate memory for them because of optimization. This once again confirms the fact that you should not try to write such code.

Kirill V. Lyadvinsky
it's not really just platform specific, it's platform, compiler AND compilation flag specific ;)
kusma
surely it is...
Kirill V. Lyadvinsky
And compiler whims specific.
shoosh
Yes, even the phase of the moon could have influence here.
Kirill V. Lyadvinsky
notice that stack allocates high memory address first. so the addresses of i and j should be larger than address of t.
Yin Zhu
Given that compiler vendors release service packs every other full moon.
shoosh
@Yin Zhu, addresses of `i` and `j` *could* be larger. It is platform specific.
Kirill V. Lyadvinsky
MSalters
Yes, that's according to C++ Standard 5.9/2: `the resultsof p<q, p>q, p<=q, and p>=q are unspecified`.
Kirill V. Lyadvinsky
+1  A: 

On windows this can be done using the _AddressOfReturnAddress intrinsic. This function gives you the address on the stack which contains the return address. the address of i,j would be a constant negative offset from that address.

Notice that any such "solution" is highly non portable and would probably fail in many cases. one such case is if the compiler decides for some reason to make i and j registers. The compiler may decide to do this since you never explicitly take the address of i or j so as far as it is concerned, its safe. In this case i,j don't actually have addresses so you're going to get the address of something else on the stack and writing on it is very likely to crash your program.

shoosh
+1  A: 

I found this works in VC compiler..

the function name takes 2 int32 in the stack, then comes the definition of a.

int find_addr()
{

int a;
printf("&a = %u &i = %u & j = %u\n", &a, &a+4, &a+3);

}
Yin Zhu
It's a duplicate of Kirill's answer.
Alexey Malistov
Not quite ... at least he knows that a stack grows downwards and not upwards ...
Goz
@Goz, It is platform specific question. For example, on Intel i960(http://www.intel.com/design/i960/) stack grows up.
Kirill V. Lyadvinsky