0

I have written a code in C in which I have defined a function which takes void* as its argument and also returns void*. I am getting few warnings and Segmentation Fault during execution. Please let me know if I am doing something silly. I am somewhat new to all these.

Code:

#include <stdio.h>
#include <stdlib.h>

void *fun1(void *a) {
    int temp = *((int*)a);             // Typecasting the received void* valud dereferencing it.
    temp++;
    return ((void*)temp);               // Returing the value after typecasting.
}

int main()
{
    printf("Hello World\n");
    int a =5;
    int *p = &a;
    int b = *p;

    printf("%d %d",a,b);

    int x = *((int*)fun1((void*)&b));     /*
                                             Here I am trying to send "b" to "fun1" function after doing a typecast.
                                             Once a value is receievd from "fun1" , I am typecasting it to int*.
                                             Then I am deferencing the whole thing to get the value in int format.
                                         */
    printf("\n%d",x);

    return 0;
}  

O/P:

main.c:8:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]                                                               
Hello World                                                                                                                                                
Segmentation fault (core dumped) 

From GDB debugger, I found that the segmentation fault is occurring at the line 20 after the value is returned from fun1(). I suspect that the way I am sending the value b to fun1() is wrong.

Also, why the intermediate printf statement in line 18 printf("%d %d",a,b); isn't executing?

dragosht
  • 3,237
  • 2
  • 23
  • 32
battyman17
  • 65
  • 6
  • `return ((void*)temp);` you are casting an `int` to a `pointer`. – mschuurmans Feb 27 '20 at 06:32
  • Your problem is in `fun1()`. Try to understand what you're actually returning from the function. Grab a pen and some paper if you have to. As for your `printf` - add a `\n` at the end. – dragosht Feb 27 '20 at 06:36
  • The return value from the function is `5`, treated as a pointer. Addresses in the first page of memory are usually invalid; you can neither read from nor write to them. So the program crashes because you have an invalid pointer that you dereference. If you changed `int x = *((int*)fun1((void*)&b));` to `int x = (int)fun1(&b));`, you probably wouldn't crash. The cast to `void *` is unnecessary; any object pointer will be converted to `void *` when required by the function prototype. (Function pointers are a different matter; they needn't be the same size as other pointer types.) – Jonathan Leffler Feb 27 '20 at 08:08

3 Answers3

2

On line return ((void*)temp); You are casting an int temp to a void*

Note that taking the address of temp is also invalid because you will get the warning warning: function returns address of local variable

You could change the funtion to return an int

int fun1(void *a) {
    int temp = *((int*)a);             
    temp++;
    return temp; // <-- Return the int value instead of a pointer.
}

And then change the calling function to

int x = fun1(&b); // <-- since fun1 now returns an integer there is no need to cast it.
mschuurmans
  • 1,088
  • 1
  • 12
  • 24
0

You dereference a non-pointer value. This is the report. I copied the error message as the follow.

=========== Start of #0 stensal runtime message ===========

Runtime error: [dereferencing a non-pointer] Continuing execution can cause undefined behavior, abort!

-
- Reading 4 bytes from an illegit address (0x6).
-
- Stack trace (most recent call first) of the read.
- [0]  file:/prog.c::23, 20
- [1]  [libc-start-main]
-

============ End of #0 stensal runtime message ============

stensal
  • 401
  • 4
  • 8
-2

Thanks to @mschuurmans for pointing out that the problem lies within the return type of fun1(). I have modified it now and it works.

    void *fun1(void *a) {
    int temp = *((int*)a);
    temp++;
    int *p = &temp;
    return ((void*)p);
    }
battyman17
  • 65
  • 6
  • 3
    That's wrong as well. You're now returning [the address of a local variable](https://stackoverflow.com/questions/12380758/error-function-returns-address-of-local-variable). – dragosht Feb 27 '20 at 06:48
  • @dragosht Yeah you are right. I shouldn't return a pointer that points to a local address. But somehow, I am not getting any errors or warnings while executing this. The o/p is as desired. Strange. – battyman17 Feb 27 '20 at 09:46