38

I am trying to return a pointer from a function. But I am getting a segmentation fault. Someone please tell what is wrong with the code

#include <stdio.h>

int *fun();

main()
{
    int *ptr;
    ptr = fun();
    printf("%d", *ptr);
}

int *fun()
{
    int *point;
    *point = 12;
    return point;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user567879
  • 5,139
  • 20
  • 71
  • 105
  • 14
    The most important question when dealing with pointers is: Pointer to _what?_ A local object? Kaboom. A dynamically allocated object? Freed by whom? Some object stored somewhere else? Then how long does that object live and how long is my pointer valid? Returning a pointer from a function is especially fraught with risk, because the pointer is initialized in a totally different piece of code (that's often not even visible to the caller), and the callers do not know how to treat the result. A good documentation for such functions is very important. – sbi Oct 13 '11 at 13:47
  • 2
    Just remember to always malloc any objects and pointers and datastructures. if you don't you'll always get a segmentation fault because it just says that we are not allocating any space for you. – Kevin Oct 13 '11 at 14:07
  • 1
    When you "change mistake in code" you make the answer (partially) unrelated to the question. Code in question isn't perfect, that's the reason for the question. I strongly recommmend to avoid fixing any code in questions. – harper May 30 '14 at 17:29
  • Hi, what exactly is the difference between doing it through `malloc` and doing it like `*ptr = 12`? Why does the former return a valid pointer to the caller even when declared locally inside the sender, while the latter doesn't? – SexyBeast Oct 03 '15 at 12:30
  • @AttitudeMonger Because `malloc` says "I want some memory to store stuff in", but plain old `*ptr = 12` says "I want some memory to do a calculation with, which can be used for other things later". – wizzwizz4 Apr 09 '16 at 10:46
  • Related: *[Returning a pointer from a function](https://stackoverflow.com/questions/12496346/)* – Peter Mortensen Oct 24 '22 at 02:56

4 Answers4

48

Allocate memory before using the pointer. If you don't allocate memory *point = 12 is undefined behavior.

int *fun()
{
    int *point = malloc(sizeof *point); /* Mandatory. */
    *point=12;  
    return point;
}

Also your printf is wrong. You need to dereference (*) the pointer.

printf("%d", *ptr);
             ^
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • If have more than one values to store, what would I do? Whether I need to allocated all or I can just increment the pointer? – user567879 Oct 15 '11 at 01:42
  • @user567879 You need to `malloc` more space. Something like `int *point = malloc(num_values * sizeof *point);` – cnicutar Oct 15 '11 at 06:30
  • 1
    Also `int *point = calloc(num_values,sizeof(int))` will be useful. More info at http://www.thinkage.ca/english/gcos/expl/c/lib/calloc.html – tremendows Aug 06 '13 at 08:42
  • Is it a good practice to return pointer from a function and make the main program to free the memory? Any other alternative to this? (only in case it is not a good practice) – Mahesha Padyana Jul 27 '15 at 17:32
  • @cnicutar: It would be better if u cast the result of malloc (to int*) although it isn't necessary in C, – Destructor Aug 19 '15 at 13:06
  • @cnicutar According to [tutorialpoint.com](https://www.tutorialspoint.com/cprogramming/c_return_pointer_from_functions.htm), it is not a good idea to return a pointer to a local object in a function. There, they give an example where the local variable is an array (stack allocation). Is it safe to allocate memory with `malloc`/`calloc` and return a pointer? As a side note, I have never experienced trouble with this practice and neither `gcc` nor `valgrind` have ever given me warnings or errors. – Pantelis Sopasakis Jun 07 '17 at 11:17
  • @PantelisSopasakis It depends on the storage class of the object to which the pointer points. If the object has "auto" storage and gets freed automatically when it goes out of scope then it's unsafe to return a pointer. But if you malloc'd the memory or if the object has "static" storage a pointer is fine. It might still be morally dubious to return memory allocated using `malloc` because then you force the caller to depend on an implementation detail and `free` it. – cnicutar Jun 07 '17 at 12:14
21

Although returning a pointer to a local object is bad practice, it didn't cause the kaboom here. Here's why you got a segfault:

int *fun()
{
    int *point;
    *point=12;  <<<<<<  your program crashed here.
    return point;
}

The local pointer goes out of scope, but the real issue is dereferencing a pointer that was never initialized. What is the value of point? Who knows. If the value did not map to a valid memory location, you will get a SEGFAULT. If by luck it mapped to something valid, then you just corrupted memory by overwriting that place with your assignment to 12.

Since the pointer returned was immediately used, in this case you could get away with returning a local pointer. However, it is bad practice because if that pointer was reused after another function call reused that memory in the stack, the behavior of the program would be undefined.

int *fun()
{
    int point;
    point = 12;
    return (&point);
}

or almost identically:

int *fun()
{
    int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

Another bad practice but safer method would be to declare the integer value as a static variable, and it would then not be on the stack and would be safe from being used by another function:

int *fun()
{
    static int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

or

int *fun()
{
    static int point;
    point = 12;
    return (&point);
}

As others have mentioned, the "right" way to do this would be to allocate memory on the heap, via malloc.

invaliddata
  • 371
  • 2
  • 4
0

It is not allocating memory at assignment of value 12 to integer pointer. Therefore it crashes, because it's not finding any memory.

You can try this:

#include<stdio.h>
#include<stdlib.h>
int *fun();

int main()
{
    int *ptr;
    ptr=fun();
    printf("\n\t\t%d\n",*ptr);
}

int *fun()
{
    int ptr;
    ptr=12;
    return(&ptr);
}
harper
  • 13,345
  • 8
  • 56
  • 105
Varun Chhangani
  • 1,116
  • 3
  • 13
  • 18
  • Doesn’t 12 exist only on the stack of that function call? That seems like it would produce undefined behavior – scape Nov 03 '17 at 20:22
-1

To my knowledge the use of the keyword new, does relatively the same thing as malloc(sizeof identifier). The code below demonstrates how to use the keyword new.

    void main(void){
        int* test;
        test = tester();
        printf("%d",*test);
        system("pause");
    return;
}
    int* tester(void){
        int *retMe;
        retMe = new int;//<----Here retMe is getting malloc for integer type
        *retMe = 12;<---- Initializes retMe... Note * dereferences retMe 
    return retMe;
}