Predict the output of the C code - c

I attended an interview where this code was written and I had to predict the output of the code.
int foo() {
int a;
a = 5;
return a;
}
void main() {
int b;
b = foo();
printf ("The returned value is %d\n", b);
}
The answer was so obvious to me and I answered 5. But the interviewer said the answer is unpredictable since the function would have been popped from the stack after return. Could anyone kindly clarify me on this?

The code as you have presented it does not have the problem the interviewer asserted it does. This code would:
#include <stdio.h>
int * foo ( void ) {
int a = 5; /* as a local, a is allocated on "the stack" */
return &a; /* and will not be "alive" after foo exits */
} /* so this is "undefined behavior" */
int main ( void ) {
int b = *foo(); /* chances are "it will work", or seem to */
printf("b = %d\n", b); /* as we don't do anything which is likely */
return 0; /* to disturb the stack where it lies in repose */
} /* but as "UB" anything can happen */

Related

Pointer as parameter in C

The code doesn't work in my Xcode compiler. It says *&point expected '('. I really don't know what goes wrong. It should have worked.
#include<stdio.h>
#include<stdlib.h>
void transformCopy(int *point);
void transformTrue(int *&point);
int main(){
int *a,*b,i=0;
transformTrue(a);
transformCopy(b);
for(i=0;i<5;i++) {a[i]=i;}
for(i=0;i<5;i++){printf("%d ",a[i]);}
printf("\n");
for(i=0;i<5;i++) {b[i]=i;}
for(i=0;i<5;i++){printf("%d ",b[i]);}
printf("\n");
return 0;
}
void transformCopy(int *point){
point=(int*)malloc(5*sizeof(int));
}
void transformTrue(int *&point){
point=(int*)malloc(5*sizeof(int));
}
*&point expected '('.
References do not exist in C ( void transformTrue(int *&point) ), this is C++ code, not C
If you want to have the equivalent in C you have to use void transformTrue(int **point) and you have to call transformTrue(&a);
If I change your code to do in C what it is done in C++ (see comments) :
#include<stdio.h>
#include<stdlib.h>
void transformCopy(int *point);
void transformTrue(int ** point); /* ** rather than *& */
int main(){
int *a,*b = 0,i=0;
transformTrue(&a); /* &a rather than just a */
transformCopy(b);
for(i=0;i<5;i++) {a[i]=i;}
for(i=0;i<5;i++){printf("%d ",a[i]);}
printf("\n");
for(i=0;i<5;i++) {b[i]=i;}
for(i=0;i<5;i++){printf("%d ",b[i]);}
printf("\n");
return 0;
}
void transformCopy(int *point){
point=(int*)malloc(5*sizeof(int));
}
void transformTrue(int ** point){ /* ** rather than *& */
*point=(int*)malloc(5*sizeof(int)); /* *point = rather than point = */
}
transformTrue(&a) modifies the value of a, but transformCopy(b); does nothing except locally (and a memory leak) and back in main the value of b is still 0, the program will crash when you will try to write in invalid addresses
one possibility is to change transformCopy like that :
int * transformCopy(){
return (int*)malloc(5*sizeof(int));
}
and of course the call to have b = transformCopy();

Printing an int in C

I am trying to print an int a before and after calling a set function to set the value of a. I am doing this in C. When I compile it I have no errors but when I attempt to run it, I get a segmentation fault.
Here is what I have so far:
#include <stdio.h>
int main(){
int* a;
printf("%d",*a);
set(10);
printf("%d", *a);
return 0;
}
int set(int*a, int val){
*a = val;
return *a;
}
int main(){
int* a;
printf("%d",*a);
What you have there is a pointer to an int rather than an actual int.
And, while that's the correct way to print the int it points to, unfortunately it points to an arbitrary memory location which is why you're crashing.
You are not allowed to dereference arbitrary pointers, they have to point to something valid, such as if you begin your code with:
int main(){
int target_of_a = 42;
int *a = &target_of_a;
printf ("%d", *a);
In addition, you probably should be calling set with something like:
set (a, 10);
something the compiler would generally warn you about though, in this case, it would probably just say it didn't know about set at the time you called it. If it had known, it could have told you about the parameter mismatch.
One way for you to acheive that is to ensure you have a prototype defined for the function before you call it:
int set(int*,int);
or just move the function to before main. With all those changes (and a bit of a general tidy up), you'd end up with:
#include <stdio.h>
int set (int *a, int val) {
*a = val;
return *a;
}
int main (void) {
int target_of_a = 42;
int *a = &target_of_a;
printf ("%d\n", *a);
set (a, 10);
printf ("%d\n", *a);
return 0;
}
The wisdom of returning the variable you're changing is also debatable but there are situations where that might be useful (such as if you want to us it immediately without another statement: printf ("%d\n", set (a, 10)); for example) so I've left that as is.
I should also mention that it's a little unusual to artificially create a pointer variable in a situation like this.
Now it may be that your code is just a simplification of some more complex scenario where you already have a pointer but, if not, the usual way to do this would be to just have the int itself and just use & to create one on the fly:
#include <stdio.h>
int set (int *a, int val) {
*a = val;
return *a;
}
int main (void) {
int a = 42;
printf ("%d\n", a);
set (&a, 10);
printf ("%d\n", a);
return 0;
}
This code should work:
#include <stdio.h>
#define FIRST_VALUE 20
#define SECOND_VALUE 10
int main(){
int a = FIRST_VALUE; /* Declare a as an int variable. */
printf("Before set: a = %d\n",a); /* Print the first value. */
set(&a, SECOND_VALUE); /* Pass the ADDRESS of a to set. */
printf("After set: a = %d\n", a); /* Print the new value of a. */
return 0;
}
int set(int*a, int val){
*a = val;
return *a;
}
Note that the variable a in main() is not the same as the variable a in set(); you have to pass a pointer to a to set() in order for set() to operate on it.
Try this:
And remember, all functions before the main() (if you're using only one file)
Take a read on value and reference params.
#include <stdio.h>
int set(int* a, int val){
*a = val;
}
int main(){
int a = 2;
printf("%d\n", a);
set(&a, 10);
printf("%d\n", a);
return 0;
}

How to realloc a memory? I keep getting segmentation fault

I keep geeting a segfault in the main function. I create a pointer to a struct I created and I pass it's reference to another function which allocates and reallocates memory. Then accessing it in the main function (where it was originally defined) causes a segfault.
Here is my test code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
char desc[20];
int nr;
} Kap;
void read(Kap *k);
int main(void) {
Kap *k = NULL;
read(k);
printf("__%s %d\n", k[4].desc, k[4].nr);
return 0;
}
void read(Kap *k) {
int size = 3;
k = (Kap*) calloc(size, sizeof(Kap));
k[0].nr = 1;
k[1].nr = 2;
k[2].nr = 3;
strcpy(k[0].desc, "hello0");
strcpy(k[1].desc, "hello1");
strcpy(k[2].desc, "hello2");
size *= 2;
k = (Kap*) realloc(k, sizeof(Kap)*size);
if(k == NULL) {
printf("ERROR\n");
exit(EXIT_FAILURE);
}
k[3].nr = 4;
k[4].nr = 5;
k[5].nr = 6;
strcpy(k[3].desc, "hello3");
strcpy(k[4].desc, "hello4");
strcpy(k[5].desc, "hello5");
}
What am I doing wrong?
Here's a simplified version of the problem you are having:
#include <stdio.h>
void func(int x)
{
x = 10;
}
int main()
{
int x = 5;
printf("x = %d\n", x);
func(x);
printf("x = %d\n", x);
}
The same reason x does not change is the reason that k does not change in your program. A simple way to fix it is this:
Kap *read()
{
Kap *k = calloc(...);
...
k = realloc(k, ...);
...
return k;
}
int main()
{
Kap *k = read();
...
}
The problem is you're not passing the pointer back to main(). Try something like this instead:
Kap * read();
int main(void) {
Kap *k = read();
printf("__%s %d\n", k[4].desc, k[4].nr);
return 0;
}
Kap * read() {
... everything else you're already doing ...
return k;
}
The code you showed passes a pointer by value into read(). The subroutine can use that pointer (though it's kind of useless since its local copy is immediately changed), however changes made within read() do not bubble back to its caller.
My suggestion is one method of allowing read() to send the new pointer back up, and it's probably the right method to choose. Another method is to change read()s signature to be void read(Kap **);, where it will receive a pointer to a pointer -- allowing it to modify the caller's pointer (due to being passed by reference).

Sending arguments to a function without parameters [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
If I have a function
int foo() {
/* stuff */
}
to which I want to send arguments (in spite the fact that it's a bad practice):
int main(void) {
int arg1 = 3;
int arg2 = 4;
foo(arg1, arg2);
return 0;
}
then, how can I refer to the arguments arg1 and arg2 inside foo()?
What's wrong with int foo(int arg1, int arg2);?
If you're unsure about the number of arguments you will be passing look into variadic functions.
This is not exactly what you want and is completely unportable but it illustrates
the principle. You probably have to adjust the offsets and the offsets will be different if the calling function (main in this case) has other variables on the stack.
And of course, if the target platform has a stack that grows in the other direction you'd have to change the loop to count down p instead.
#include <stdio.h>
int foo(void) {
int *p;
int a, b;
int i;
for (i = 0; i < 32; i++) {
p = (&i + i);
printf("i %d : p %p %d\n", i, p, *p);
}
a = *(&i + 11);
b = *(&i + 10);
printf("a %d\n", a);
printf("b %d\n", b);
return a + b;
}
int main(void) {
int a = 8;
int b = 2;
foo();
return 0;
}
And for the record, this kind of stuff is both fun and useful. In particular, it can be invaluable to know when debugging. So I think the question is a good one. That does not mean that this kind of thing should ever end up in any "production" code.
You can solve it by having a global state and a helper function:
static int foo_i, foo_j;
static void foo_setup(int i, int j) {
foo_i = i; foo_j = j;
}
int foo() {
return foo_i % foo_j;
}
int main() {
foo_setup(10,40);
printf("%d\n", foo());
}
To decide whether this is suitable for you, you must consider that this solution is non-reentrant. If you are using threads, you may need to synchronise the calls to foo_setup and foo. Similarly, if you will not call foo immediately after calling foo_setup, you need to carefully craft your code to not use code calling foo_setup, in between.
If you can use c++, you can pass the arguments through the constructor and define an operator() method for the struct.
Thank you for the suggestions. The solution I suggest for the problem I introduced is as follows:
static int helper(int argc, ...) {
unsigned *argv = (unsigned *) (void *)(&argc + 1);
switch (argc) {
case 0: /* do stuff */
case 1: /* do stuff with argv[0] */
case 2: /* do stuff with argv[0], argv[1] */
...
case n: /* do stuff with argv[0], argv[1], ..., argv[n] */
}
}
int goo(void) {
return helper(0);
}
int bar(int arg1) {
return helper(1, arg1);
}
int foo(int arg1, int arg2) {
return helper(2, arg1, arg2);
}
int main(void) {
int arg1 = 3;
int arg2 = 4;
return foo(arg1, arg2);
}

C puzzle: Output of printf should be '5' always

I found this puzzle in a C aptitude paper.
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
}
int main()
{
int i = 5;
change();
i = 10;
printf("%d", i);
return 0;
}
Any solutions.?
define?
#include <stdio.h>
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
#define printf_ printf
#define printf(a, b) printf_("5");
}
int main()
{
int i = 5;
change();
i = 10;
printf("%d", i);
return 0;
}
This is a POSIX answer that really does what the problem asks :)
It won't work on some architectures/compilers but it does here.
#include <stdio.h>
void
change () {
void _change();
_change();
}
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
void
_change()
{
int main();
uintptr_t m=(uintptr_t)main;
uintptr_t ps=sysconf(_SC_PAGESIZE);
m/=ps;
m*=ps;
mprotect((void*)m,ps,PROT_READ|PROT_WRITE|PROT_EXEC);
char *s=(char*)(intptr_t)main;
s=memchr(s,10,ps);
*s=5;
mprotect((void*)m,ps,PROT_READ|PROT_EXEC);
}
int
main() {
int i=5;
change();
i=10;
printf ("%d\n",i);
return 0;
}
EDIT: This should make it more robust for people with boycotting headers.
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
#define i a=5,b
}
Here's a really cheap answer:
void
change()
{
printf("%d", 5);
exit(0);
}
:-P
Here's another possibility:
void change()
{
char const *literal = "%d";
char * ptr = (char*)literal;
ptr[0] = '5';
ptr[1] = 0;
}
This is much more portable than changing the return address, but requires you to (a) have a compiler that pools string literals (most do), and (b) have a compiler that doesn't place constants in a read-only section, or be running on an architecture with no MMU (unlikely these days).
Anybody thought of using atexit?
void change (void)
{
static int i = 0;
if (i == 0) atexit (change);
if (i == 1) printf ("\r5 \b\n");
++i;
}
Note that there is no terminating newline in the main function, if we send 2 backspace characters to stdout, the 10 will be erased, and only the 5 will be printed.
Invoke the requisite #include, and replace the comment with the parenthesis-unbalanced text:
}
int printf(const char *s, ...) {
return fprintf(stdout,"%d",5);
Tested successfully. Thanks to dreamlax and Chris Lutz for bugfixes.
You have a local variable i in the stack that has a value of 5 to begin with.
With change(), you need to modify the next instruction to be 5 so you would need to buffer override to that location where 10 is set, and have it set to 5.
The printf("%d", i); call in main() doesn't end its output in a newline, the behavior of the program is implementation-defined.
I assert that on my implementation, a program that fails to write a terminating newline for the final line always prints 5 followed by a newline as its last line.
Thus, the output will always be 5, whatever the definition of change(). :-)
(In other words, what's the point of such questions, unless they're meant to run on particular hardware, compiler, etc.?)
void change()
{
#define printf(x,y) fprintf(stdout,x,y-5)
}
Simple:
void change()
{
printf("%d\n", 5);
int foo;
close(0);
close(1);
dup2(foo, 1);
dup2(foo, 0);
}
Slightly more sophisticated:
void change()
{
int *outfd = malloc(2 * sizeof(int));
char buf[3];
pipe(outfd);
if(!fork())
{
read(outfd[0], buf, 2);
if(buf[0] == '1' && buf[1] == '0')
{
printf("5\n");
}
else
{
write(1, buf, 2);
}
while(1);
}
else
{
close(1);
dup2(outfd[1], 1);
}
}
I suspect that the "correct" answer to this is to modify the return address on the stack within the change() function, so that when it returns the control flow skips the i=10 command and goes straight to the printf.
If so then that is a horrible, ugly question and the (non-portable) answer requires knowledge of the architecture and instruction set used.
How about something like this: (x86 only)
change()
{
__asm__( "mov eax, [ebp+4]\n\t"
"add eax, 4\n\t"
"mov [ebp+4], eax\n\t" );
}
Loving the answers in here. I got it to work in two lines.
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
/* print a 5 */
printf("5\n");
/* Close standard output file descriptor */
close(1);
}
int main()
{
int i = 5;
change();
i = 10;
printf("%d", i);
return 0;
}
The 10 will never reach the output because after the change() function prints a 5, the stdout file descriptor is closed.
People can verify that using the following online C compiler.
http://www.tutorialspoint.com/compile_c_online.php
here is a different one:
void change()
{
#define printf(x,y) printf("5",x,y);
}
do I get the "smallest #define to solve a silly problem award"?
I am not sure this would always work, but what about locating the i variable on the stack like this:
void change()
{
int j, *p;
for (j=-100, p=&j; j<0; j++, p++)
if (*p == 10) { *p = 5; break; }
}

Resources