I can't tell you the answer to your problem. But I can write a program which might, maybe, find the answer to your problem.
Try running this program:
#include <stdio.h>
int main2(int off)
{
int n;
int a[5];
int *p;
a[2] = 1024;
p = &n;
p[off] = 98;
return a[2];
}
int main()
{
int i;
for(i = -5; i <= 5; i++)
if(main2(i) == 98)
printf("the magic offset is %d\n", i);
}
On my computer, with one of my compilers, today, this program prints
the magic offset is 4
That tells me that (on my computer, with that compiler, today) the "solution" to your ridiculous problem would be
#include <stdio.h>
int main()
{
int n;
int a[5];
int *p;
a[2] = 1024;
p = &n;
p[4] = 98;
printf("a[2] = %d\n", a[2]);
}
I'm not even going to try to explain why this works, because the reasons are so obscure, unrepeatable, and meaningless. (See this question's other good answers for more details.) Basically the first program automates the search for a magic offset from p, more or less as you discovered.
And, in fact, under the first compiler I tried it, it didn't even work. Despite using the magic number 4 that the first program discovered, the second program printed a[2] = 1024. That's not too surprising: the relative positions of variables like a, p, and n are not specified by any standard. They're totally up to the compiler. The compiler is perfectly within its rights to arrange them one way in function main2 in my first program, and a completely different way in function main in my second program.
I tried my first program under a different compiler, and it printed
the magic offset is -3
and then crashed with a segmentation fault. But then, under that compiler, when I changed the relevant line in the second program to
p[-3] = 98;
it "worked", printing a[2] = 98 as required.
(And then I tried turning up the optimization level, and it stopped working.)
To be perfectly clear, the fact that my approach did not work under that first compiler, because it failed to arrange things in a consistent or predictable way, does not mean there's anything wrong with that compiler! Quite the contrary: the fault is entirely in the broken programs I wrote, and the broken assignment of yours that motivated them.
Here is an alternative exercise which will teach you something useful about arrays and pointers, without requiring that you "learn" false, unrepeatable facts about how variables are or aren't guaranteed to be arranged in stack frames.
#include <stdio.h>
int main(void)
{
int a[5];
int *p;
a[2] = 1024;
p = &a[4];
/*
* write your line of code here...
* Remember:
* - you are not allowed to use a
* - you are not allowed to modify p
* - only one statement
* - you are not allowed to code anything else than this line of code
*/
/* ...so that this prints 98\n */
printf("a[2] = %d\n", a[2]);
}
This problem has a similar solution — you can easily work it out — but the solution is unique and guaranteed to work, because it depends on well-defined properties of arrays and pointer arithmetic in C, not on accidental details of the stack layout.