0

I have a binary file which contains N numbers from an array. I want to return a pointer to the elements in the array.

float *** reading(char* read_from) {
    float x[n], *p;
    p=x;
    int i;
    FILE *fh= fopen (read_from, "rb");
    for (i=0;i<2*n*n;i++)
        fread (&x[i], sizeof (x[i]), 1, fh);
    fclose (fh);
    return p;
}

int main()
{
    float *var;
    char *file="input.bin"; //this would be user input
    var=reading(file);
    printf("%f",*var);
}

If I'm running this, the content of var gets deleted after I handle it. I tried switching to another pointer (declaring a var1) and it is not working.

Edit: The function header is mandatory. It can not be modified.

ClaudiusDan
  • 243
  • 1
  • 12
  • 2
    The indentation here is total chaos. Can you fix that? – tadman Jan 03 '18 at 19:47
  • 7
    It's entirely unclear why the return type of `reading` is `float***`. It's also returning a pointer to a stack-allocated `x` which falls out of scope, so that's undefined behaviour. – tadman Jan 03 '18 at 19:48
  • 1
    Who the h*** forces you to become a [three star programmer](http://wiki.c2.com/?ThreeStarProgrammer)? It's *not* a compliment to be called that. As for the rest of the code, perhaps you misunderstand what you're supposed to do? – Some programmer dude Jan 03 '18 at 19:54
  • I need to return a pointer to the array containing the values from the file. – ClaudiusDan Jan 03 '18 at 19:57
  • You need to allocate memory on the heap – Christian Gibbons Jan 03 '18 at 19:59
  • @ClaudiusDan Well you've allocated space for your `float *`, but you are returning a `float ***`, so you'd need to allocate space for the `float **` that holds your `float *`, and for the `float ***` that holds your `float **`. All of this just to satisfy the necessity of returning a `float ***`. – Christian Gibbons Jan 03 '18 at 20:32
  • @ClaudiusDan With all that said, looking at the math you are using to calculate how much to allocate, I can't help but wonder if the intention of this is to be a 3D array. – Christian Gibbons Jan 03 '18 at 20:36
  • @ChristianGibbons Thank you for your time. I figured that this is total garbage and I will create it with just one pointer. The numbers in the binary file represent the elements of two matrices. I needed to create a function that points to an array containing the elements from both matrices. – ClaudiusDan Jan 03 '18 at 20:39
  • You can't (safely) return pointers to local arrays — hence the duplicate. You also appear to have or possibly two too many stars in your return type. Being a [Three-Star Programmer](http://c2.com/cgi/wiki?ThreeStarProgrammer) is not a good idea. Occasionally, it may be necessary; it almost certainly isn't necessary here. – Jonathan Leffler Jan 03 '18 at 21:40

2 Answers2

0

The problem is that when you create the local variable, in this manner *p pointer to local array variable float x[n], it is allocated on the stack and is hence unavailable once the function finishes execution. That is, you call the tune until end of its scope. So it causes undefined behaviour.

0

One problem is that you return the address of a local variable (with automatic storage duration), which's lifetime ends at the end of the function. Dereferencing such a pointer after the lifetime has ended is undefined behaviour. If n is a compile time constant, a quick fix would be to declare the array static, such that its lifetime is up to the end of your program. Otherwise, you'll either have to pass the buffer to the function or let the function create the buffer dynamically.

Further, your return type is pointer to pointer to pointer to float, which cannot be reinterpreted as a pointer to float.

And you read in up to 2*n*n values, whereas your array is declared of size n. BTW: you can read in the buffer in one step (no need for a loop here).

The following code should fix these issues:

float * reading(char* read_from) {
    float *p = calloc(2*n*n, sizeof(float));
    FILE *fh= fopen (read_from, "rb");
    fread (p, 2*n*n, sizeof (float), fh);
    fclose (fh);
    return p;
}

Note that the caller is obliged to free the memory once not uses any more.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58