Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs

Dashboard
Notifications
Mark all as read
Q&A

Invalid memory access when trying to dereference a pointer obtained through a function call

+4
−0

Hey, regarding a question on returning pointers as functions, why does my code produce this error & won't print out the sum = 6? Code error Pop-up error message

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

int *Add(int *a, int *b){ 
    int c = (*a) + (*b);     
    return &c;
}

int main (){ 
    int x=2, y=4;
    int *Ptr = Add(&x,&y); 
    printf("Sum = %d\n",*Ptr);
}
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

1 comment thread

Avoid image of code or errors (2 comments)

1 answer

+6
−0

Your function returns a pointer to a local non-static variable. Such a variable exists only during execution of the function and is removed on return. This means you are left with a so-called dangling pointer, a pointer that points to a no longer valid address.

Note that using such a pointer is undefined behaviour, that is, the compiler may do whatever it wants. Apparently the compiler was helpful by turning that pointer into a null pointer, thus guaranteeing you to get an error instead of unexpected results (or worse, expected results during testing and unexpected results later when using the code on important data).

Note that the compiler did warn you about that problem. The screenshot you posted contains the following message:

warning: function returns address of local variable

There are several ways to fix this. The most obvious for this function is, of course, returning the value instead; however there are cases where you cannot do that (e.g. if what you return is not a single value, but an array).

If the function is required to give the pointer as return value, the best way to do it is to allocate new memory inside the function. The downside is that the caller is then responsible for freeing that memory. The code would then look like this:

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

int *Add(int *a, int *b){
    /* allocate memory */
    int *c = (int*)malloc(sizeof(int));

    /* write to that memory */
    *c = (*a) + (*b);
    return c;
}

int main(){ 
    int x=2, y=4;
    int *Ptr = Add(&x,&y); 
    printf("Sum = %d\n",*Ptr);

    /* Free the memory allocated by Add */
    free(Ptr);
}

Another option is to pass the pointer for the result as additional argument to the function instead (in more realistic scenarios you'll also pass the size of the available memory as additional parameter, but for this function it's not necessary):

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

void Add(int *a, int *b, int *c){
    /* write to the memory passed to the function */
    *c = (*a) + (*b);
}

int main(){ 
    int x=2, y=4;
    int result;
    Add(&x, &y, &result); 
    printf("Sum = %d\n",result);
}

There's also another solution that is simpler, but should be used only in exceptional cases: You can declare the local variable as static. That way it stays valid on return. However it also means that all calls to the function share the same variable, which means if you are not careful, you might change the variable before you read it. It also causes major problems if you want to use the function in multithreaded code.

Using a static local variable, the changes to your code are minimal:

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

int *Add(int *a, int *b){ 
    static int c;
    c = (*a) + (*b);     
    return &c;
}

int main(){ 
    int x=2, y=4;
    int *Ptr = Add(&x, &y);
    printf("Sum = %d\n", *Ptr);
}

The following shows an example why this method is generally problematic:

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

int *Add(int *a, int *b){ 
    static int c;
    c = (*a) + (*b);     
    return &c;
}

int main(){ 
    int x1=2, y1=4;
    int *Ptr1 = Add(&x1, &y1);
    int x2=6, y2=8;
    int *Ptr2 = Add(&x2, &y2);
    printf("Sum 1 = %d\nSum 2 = %d\n", *Ptr1, *Ptr2);
}

Contrary to what you'd expect when reading main, this code will output

Sum 1 = 14
Sum 2 = 14

This is because the second call to Add overwrites the value of c, to which Ptr1 points.

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »