Adobe Interview Question for Software Engineer / Developers


Country: India
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
6
of 6 vote

int fun()
{
#define fun() i = 20
        return 0;
}
int main()
{
	int i=10;
	fun();
	printf("%d",i);

}

- Chris November 03, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice its working....

- Rohit Jain November 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

nice solution ...

- Anonymous November 11, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

#define is not working because it is having block scope so it will not work.....

- balu November 29, 2014 | Flag
Comment hidden because of low score. Click to expand.
4
of 4 vote

in 64bit os, compiled with gcc;

int fun()
{
	/*write code here.*/
	int p[0];
	p[8] = 20;
}
int main()
{
	int i=10;
	fun();
	printf("%d",i);
}

- Abhi October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Explain..?

- TechGuy October 28, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

please please please explain ???

- niyati October 28, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Its about memory layout of functions and variable.
if you disassemble the excutable you will find this

(gdb) disas fun
Dump of assembler code for function fun:
   0x000000000040052d <+0>:	push   %rbp
   0x000000000040052e <+1>:	mov    %rsp,%rbp
   0x0000000000400531 <+4>:	movl   $0x14,0x1c(%rbp)
   0x0000000000400538 <+11>:	pop    %rbp
   0x0000000000400539 <+12>:	retq   
End of assembler dump.
(gdb) disas main
Dump of assembler code for function main:
   0x000000000040053a <+0>:	push   %rbp
   0x000000000040053b <+1>:	mov    %rsp,%rbp
   0x000000000040053e <+4>:	sub    $0x10,%rsp
   0x0000000000400542 <+8>:	movl   $0xa,-0x4(%rbp)
   0x0000000000400549 <+15>:	mov    $0x0,%eax
   0x000000000040054e <+20>:	callq  0x40052d <fun>
   0x0000000000400553 <+25>:	mov    -0x4(%rbp),%eax
   0x0000000000400556 <+28>:	mov    %eax,%esi
   0x0000000000400558 <+30>:	mov    $0x4005f4,%edi
   0x000000000040055d <+35>:	mov    $0x0,%eax
   0x0000000000400562 <+40>:	callq  0x400410 <printf@plt>
   0x0000000000400567 <+45>:	leaveq 
   0x0000000000400568 <+46>:	retq   
End of assembler dump.

in memory layout, function fun resides before main. So, you can access main function's internal variable via pointer arithmetic.

Now, all you have to find is relative location for i from the place you are assigning the value.

- Abhi October 29, 2014 | Flag
Comment hidden because of low score. Click to expand.
4
of 4 vote

It's a local, the scope of which is the function - main. Compilers put it on the stack, the stack grows down.

Declare a local in fun(), mine's called 'i'. The address of fun():i is on the stack. There are only pointers above it: stack and code pointers. We can use this to say anything on the stack which has the value '10' is our initialised integer from main. We then write '20' to that address.

{{
#include <stdio.h>
int fun()
{
/* Wander up the stack in integer pointers look for the number 10 & change it to 20.*/
int i;
int *p=&i;
int j;
for(j=0;*(p+j)!=10;j++){
;
}
/* Stack Frame size is j int pointers. */
*(p+j)=20;
}
}}

- Shaun October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

+1
Tested. It works.

- ninhnnsoc October 28, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

very very thankz for your code but plese tell me how u do that ??
i can't understand what you have done ?
how you reached main::i ??
please explain how ????

- niyati October 28, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I think motivation of this question has come from reading phrack magazine.
Shaun answer is right however there is assumption there that stack will go downwards and memory allocation will go upwards.

- aka October 28, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

I did something functionally equivalent, and as expected, it works only with all optimizations disabled. If you turn on typical release build optimizations, all bets are off! For example, my compiler (VS2013) with maximize speed turned on, optimizes away the existence of main::i altogether. It inlines fun() ahead of the call to printf(), and then pushes the value 10 directly onto the stack *after* calling fun(), just before calling printf. There is no way to know at compile time that main::i is being accessed from fun(), so this is obviously a very unsafe way to code (which your interviewer probably expected you to point out).

Secondly, even without optimizations, I don't think you can guarantee this technique to work 100% of the time. What if, while walking the stack, an int-sized chunk of something else happens to evaluate to 10 when interpreted as an int?

- adam October 28, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

i think assembly language will be used

- mohit sharma October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. pass i as a pointer to the function and update the value of i.
2. Since I is a local to main and is initializedd, it will be held in the bss segment of the user program. Inside the function fun which will be put onto stack, if we have access to the bss segment by manipulating the address and updating the value at that address.

- Anonymous October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Niyati, where are you struggling. There's text, data & stack segments... C pointers are actual addresses ... The difficult bit is stacks;
Google wikipedia computer hardware stack Select the first answer and check #Hardware_stacks

If you have a pointer to 'somewhere' on the stack you can look at the adjacent locations until you find the variable main::i.

This answer is about C pointer arithmetic and memory layout. Extra points could be earned for the mechanisms used to obfuscate stack addresses, write protecting memory etc.

- Shaun October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

jayada hva me mat ud..... ch******

- niyati October 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Horrible question. There is no way to do this in pure C in a reliable way. The stack may grow in either direction, depending on the architecture. The compiler may decide to keep i in a register when assigned 10 in the main, so any change to memory done in fun() would have no effect on the result of the printf.

- Anonymous October 29, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I agree. There is no portable safe way to access main::i from fun() and you can easily create infinite loops or corrupt the stack trying the search and replace trick.

I would give the interviewee half the credit for thinking of trying to walk back the stack, and the other half for coming up with the conclusion that this is unsafe and providing at least 2 ways it could fail. There are multiple failure cases from compiler optimizations alone (main::i not allocated on the stack, or not at all, functions re-ordered due to no compiler-detectable dependencies, etc.), the issue of non-uniqueness of the searched-for value on the stack, hardware implementation issues that make code non-portable. On some systems you could subtract pointers to sequentially-declared local variables and dynamically detect which way the stack grows, slightly increasing your portability success rate, but event this is something the compiler is free to thwart, particularly with optimizations turned on.

- adam October 29, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Making the function fun() inline should work right ?

- Anon December 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

any "hack" will lead to the unexpected behavior. to explain what I'm saying: compiler allows to move "int i = 10;" statement after calling fun(); or even remove i variable at all.

- ultras October 29, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#define printf (d, s) d=20;

- scourge99 November 13, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

#define printf (s, d) d=20;

- scourge99 November 14, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

func()
{
__asm__("movl $20,%eax");

}

int main() {
int i = 10;
func();
printf("%d \n", i);
return;

- ano2 May 18, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote
{{{ #include <stdio.h> int fun(){ int var = 0; int *p = &var; while((*p) != 10){ p++; } *p = 20; } int main(){ int i = 10; fun(); printf("%d",i); return 0; } - rootknox June 30, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <stdio.h>

int fun(){
	int var = 0;
	int *p = &var;
	while((*p) != 10){
		p++;
	}
	*p = 20;
}

int main(){
	int i = 10;
	fun();
	printf("%d",i);
	return 0;
}

- sassi.aissa.takieddine June 30, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

How about:

int fun()
{
	int i = 5;
	printf("%d", i);
	exit(EXIT_SUCCESS);
}

int _tmain(int argc, _TCHAR* argv[])
{
	int i = 5;
	fun();
	printf("%d", i);
	return 0;
}

- Alex Superdev October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You have to change the value of i from main function. Not just print it.

- Abhi October 29, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

int fun(&temp)
{
temp=20; /*write code here.*/
}
int main()
{
int i=10;
fun(i);
printf("%d",i);
}

- Anonymous October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You can not modify main function.

- Abhi October 29, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

in turbo compiler
void fun()
{
int p=0,*q;
q=(&p)+3;
*q=20;
}
void main()
{
int i=20;
fun();
printf("%d",i);
getch();
}

- sudhirthakur4 November 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 vote

int fun(&temp)
{
temp=20; /*write code here.*/
}
int main()
{
int i=10;
fun(i);
printf("%d",i);
}

- Anonymous October 28, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

func()
{
__asm__("movl $20,%eax");

}

int main() {
int i = 10;
func();
printf("%d \n", i);
return;
}

- Anil Kumar April 25, 2015 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More