2

I am trying to implement a simple program using a header file where a function in the header file accepts an int array and returns an int array too.

In header.h:

int* point(int a[]);

In header.c:

#include<stdio.h>
#include "header.h"

int* point(int a[])
{
 printf("In the point function\n");
 int array[4],i;
 for(int i=0;i<4;i++)
 {
    printf("%dth Iteration\n",i);
    array[i]=a[i];
 }

return array;
}

In test.c:

#include<stdio.h>
#include "header.h"
void main()
{
 int *array,i;
  int a[]={1,2,3,4};
   printf("calling point function\n");
  array=point(a);
  printf("Back in the main function\n");
  for(i=0;i<4;i++)
  {
    //SEGMENTATION FAULT HERE
    printf("%d\n",array[i]);
  }

}

I am getting a segmentation fault at the print loop in test.c.

NAND
  • 663
  • 8
  • 22
Magnum
  • 83
  • 1
  • 5
  • The array inside of the `point()` goes out of scope and gets destroyed as soon as the function returns. Instead create the array in `main()` and pass a pointer to it as an argument. – HolyBlackCat Jan 30 '17 at 01:56
  • You are returning the address of an array created on the stack, then destroyed at the end of the function. The lifetime of the array named array is too short. The array does not exist after the function named point completes. – Jim Rogers Jan 30 '17 at 01:58
  • creating a `int array[4]` will create that array on the stack. Then you exit the method, all memory associated with that method-call gets lost (except the returned value) and the returned pointer points to a position on the stack that doesn't exist anymore. –  Jan 30 '17 at 01:58

3 Answers3

3

You cannot return arrays from functions. When point() returns, the local array within this function goes out of scope. This array is created on the stack, and will get destroyed once the function finishes returning. All memory associated with it is discarded, and the returned pointer points to a position on the stack that doesn't exist anymore. You need to instead allocate a pointer on the heap, and return that instead. This allows array to be shared across your program.

Instead of:

int array[4];

you need to dynamically allocate a pointer using malloc():

int *array = malloc(4 * sizeof(*array)); /* or sizeof(int) */
if (array == NULL) {
    /* handle exit */
}

malloc() allocates requested memory on the heap, and returns a void* pointer to it.

Note: malloc() can return NULL when unsuccessful, so it needs to be checked always. You also need to free() any memory previously allocated by malloc(). You also don't need to cast return of malloc().

Another thing to point out is using the magic number 4 all over your program. This should really be calculated using sizeof(a)/sizeof(a[0]).

You can declare this as a size_t variable in your main():

size_t n = sizeof(a)/sizeof(a[0]);

Or you can use a macro:

#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))

And simply call ARRAYSIZE(a) everytime you want the size of the array.

Community
  • 1
  • 1
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
2

The issue has to do with the scope of the array variable that you're returning in your method. Right now you're returning array, a local variable defined in the method, point. However, once point is finished executing, all local variables within the function frame, including array will be discarded from main memory. So even though you still get a memory address from point, there's no telling what could be at that memory address. Therefore, treating array as an int array when printing out its elements will lead to a segmentation fault.

My suggestion to fix this is to allocate memory from the heap using malloc so that array lasts outside the frame of point. The solution should look like this,

int* point(int a[])
{
 printf("In the point function\n");
 int *array = (int *) malloc(4 * sizeof(int)); //dynamically allocate memory for 4 integers
 int i;
 for(i=0;i<4;i++)
 {
    printf("%dth Iteration\n",i);
    array[i]=a[i];
 }

return array;
}
Chris Gong
  • 8,031
  • 4
  • 30
  • 51
0

You could either define array[] as a global variable, or dynamically allocate memory for it as mentioned in the above comments using malloc(). Since array[] is allocated in the function point(), it gets deleted once the function exits. Hence, a reference to the returned pointer causes a segmentation fault.

NAND
  • 663
  • 8
  • 22
k20392
  • 11
  • 1