2

I have a file who has num lines: every line contains one number. I want to save every number into a vector *vet. Why this code doesn't work?

Segmentation fault (core dumped)

I think that the error is sscanf in save_numbers function, but I don't know why.

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

/* This function allocate memory
and save numbers into a vector */
int save_numbers (int **vet, int *num)
{
    FILE *fin;
    int i = 0;
    char buff[10];

    if ( !(fin = fopen("numbers.dat", "r")) )
        return 1;

    while ( fgets(buff, sizeof(buff), fin) )
    {
        *vet = (int *) realloc (*vet, (i+1) * sizeof(int) );
        sscanf (buff, "%d", vet[i]);
        i++;
    }

    *num = i;

    return fclose(fin);
}

int main ()
{
    int i, num, *vet = NULL;    

    if ( save_numbers(&vet, &num) )
    {
        perror("numbers.dat");
        exit(1);
    }

    /* print test */
    for (i=0; i<num; i++)
        printf ("%d ", vet[i]);
    printf("\n");

    free(vet);

    return 0;
}

Example of file here: http://pastebin.com/uCa708L0

ᴜsᴇʀ
  • 1,109
  • 2
  • 9
  • 23
  • `If ptr does not match a pointer returned earlier by calloc(), malloc(), or realloc() or if the space has previously been deallocated by a call to free() or realloc(), the behavior is undefined.` From http://pubs.opengroup.org/onlinepubs/009695399/functions/realloc.html – A Person Jan 12 '14 at 22:41
  • You set `int *vet` to NULL, you have to allocate memory to it first, before you can reallocate its memory. Change it to an array with a preset maximum length, like `int vet[MAX_NUM_OF_NUMS] = {0};`, where `MAX_NUM_OF_NUMS` is the maximum no. of numbers you can expect. Then you can do away with the realloc. – A Person Jan 12 '14 at 22:42
  • Or, change `vet`'s declaration to `int *vet = malloc(sizeof(int));` – A Person Jan 12 '14 at 22:47
  • 1
    @A Person But if I want to do it with `int *vet` and not with a `int vect[MAX_NUM_OF_NUMS]` what can I do? I use `realloc` to allocate the exact size of memory for contain the numbers. – ᴜsᴇʀ Jan 12 '14 at 22:48
  • @A Person Ok thanks, now I try to change into `int *vet = malloc(sizeof(int));`. – ᴜsᴇʀ Jan 12 '14 at 22:48
  • @A Person I have change declaration to `int *vet = malloc(sizeof(int));` but it doesn't work! `Segmentation fault (core dumped)` – ᴜsᴇʀ Jan 12 '14 at 22:51
  • Change `*vet = (int *) realloc (*vet, (i+1) * sizeof(int) );` to `vet = realloc (vet, (i+1) * sizeof(int) );` – A Person Jan 12 '14 at 22:52
  • If that works, then change `int *vet = malloc(sizeof(int));` back to `int *vet;`. – A Person Jan 12 '14 at 22:55
  • @A Person If i make the change you suggest I receive this: http://pastebin.com/sMau2xDJ – ᴜsᴇʀ Jan 12 '14 at 22:56
  • Do this, `int* new_vec = realloc(vet, (i+1) * sizeof(int));` and test if `new_vec` is NULL. If it is not, then do `vec = new_vec;`, else the program couldn't allocate additional memory. See http://stackoverflow.com/questions/8319216/using-realloc-in-c for more info on using realloc – A Person Jan 12 '14 at 22:59
  • 2
    But why? `*vet = (int *) realloc (*vet, (i+1) * sizeof(int) );` isn't correct? – ᴜsᴇʀ Jan 12 '14 at 23:00
  • `vet` is a pointer to an int, `*vet` is the data that `vet` points to, so `*vet` is an int. realloc takes in a pointer to anything and a size_t. If realloc returns NULL then vet would be set to NULL, use a temp value to store the returned pointer and check if it is valid – A Person Jan 12 '14 at 23:01
  • But isn't like this http://stackoverflow.com/a/21067718/3185964 ? – ᴜsᴇʀ Jan 12 '14 at 23:04
  • If you are referring to the `memoria` function, vet is of type `int**` meaning it is a pointer to a pointer to a int. Meaning *vet is a pointer to an int and **vet is an int. Here, vet is of type `int*`, so vet is a pointer to an int. &vet is the address of the pointer that points to an int and so &vet is a pointer to a pointer to a int. I admit this could be bloody confusing, recommend reading up more on pointers – A Person Jan 12 '14 at 23:05
  • Sorry but I'm confused... From the code I had wrote, what changes should I do? – ᴜsᴇʀ Jan 12 '14 at 23:08
  • Change the code to the code you have now, so I can see what changes you made – A Person Jan 12 '14 at 23:09
  • 1
    let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/45071/discussion-between-a-person-and-user) – A Person Jan 12 '14 at 23:09
  • 1
    Minor: suggest larger size for `char buff[10];`, at least `char buff[13];` for "-2147483648\n" or 2x that for growth. – chux - Reinstate Monica Jan 13 '14 at 01:30
  • 1
    _@chux_.What do you mean with `or 2x that for growth.` – ᴜsᴇʀ Jan 13 '14 at 01:32

1 Answers1

5

change

sscanf (buff, "%d", vet[i]);//vet : int **

to

sscanf (buff, "%d", &(*vet)[i]);
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70