views:

242

answers:

3

The line *array[cnt] = thing causes a seg fault and I don't know why. Any ideas to fix this?

long *Load_File(char *Filename, int *Size)
{
    FILE *fp;

    if((fp = fopen(Filename,"r")) == NULL)
    {
        printf("Cannot open file.\n");
        exit(-1);
    }

    fscanf(fp,"%d",Size);

    int cnt = 0;
    int items = *Size;
    long * array[items];
    int thing;

    while (!feof(fp))
    {
        fscanf(fp,"%d",&thing);
        *array[cnt] = thing;
        cnt++;
    }

    fclose(fp);

    return *array;
}
+3  A: 
long * array[items];

is declaring an array of pointers to long data type. But these pointers are not pointing to anything meaningful.

When you do

*array[cnt] = thing;

you are dereferencing the pointer which is incorrect since they dont point to anything meaningful.

You can dynamically allocate the memory for the array as:

long * array = (long*) malloc(size(long) * items);

and then do:

while (!feof(fp)) {
        fscanf(fp,"%d",&arr[cnt++]);
    }

and then return the array as:

return array;
codaddict
You need to make sure your file has a number "items" followed by at max those many numbers.
codaddict
A: 

First off, that code can't compile. Since items isn't a constant, it can't be used to size the array. How did you get it to even run, let alone seg-fault? Aside from that, and in addition to the problem @codaddict highlights...

feof won't return true until fscanf fails. This will push you past the end of the array. Better to write this:

while (cnt < items && fscanf(fp, "%d", &thing))
{
    /* ... */
}

WRT the array, I think you intended this:

long *array = malloc(sizeof(long)*items);
/* ... */
    array[cnt] = thing;
/* ... */
return array;
Marcelo Cantos
While everything else you said is correct, even `return array;` is wrong because `array` is local to the function, so you can't `return `.
Alok
You /can/ compile it using variable length arrays. However, as ergosys reminded us, you should never return a pointer to your stack (which includes VLAs). Alok, return array is not wrong. Since he malloced, array is pointing to heap memory, which is fine.
Matthew Flaschen
@Matthew, thanks for pointing that out. I'm a pre-C99 programmer.
Marcelo Cantos
A: 

Change

long * array[items];

to

long * array = (long *) malloc(sizeof(long) * items);

We dynamically allocate memory for items longs and store the address in our array variable. Your syntax means "An array of items pointers to long". The new syntax means "a pointer to a long" (the first of a dynamic "array").

Change

    *array[cnt] = thing;

to

    array[cnt] = thing;

We put the latest read long in the correct spot.

Change

return *array;

to

return array;

We return array, which is the same as a pointer to the first long in the memory we allocated. Be sure to free it later.

EDIT:

Thanks to ergosys for reminding me that VLAs are allocated on the stack. Removed suggested changes to function header.

Matthew Flaschen
All good except the last part! Returning a pointer to stack memory is bad juju.
ergosys
the function header is predefined and im not allowed to change it
pythonicate
What ergosys said, but it also looks like he's supposed to be returning the Size value that he reads to a variable provided by the caller (i.e. Size appears to be an [out] parameter). Filename is probably an [in], although it's not const, so who knows. The return value presumably is an array of longs, so I assume that the expectation was for the function to allocate the array on the heap and return the pointer.
Scott Smith