0

Here's my problem : I've a 2d char matrix wich I malloc with a function. Afterward, I want to get a map from a file, but I've got a segmentation fault right there and I dont know why... Here's a code sample :

// struct where I put the map and others informations from the  
typedef struct problem_t
{
    char *nom;
    Coordonnees arrivee, depart;
    int nb_ligne, nb_col;
    char **     
} Problem;

// Function wich malloc the map
int mallocCarte( char *** carte, int nbLigne, int nbCol )
{
    *carte = malloc( nbLigne * sizeof( char* ) );

    if ( *carte == NULL )
    {
        return false;
    }

    int i;
    for ( i = 0; i < nbLigne ; ++i )
    {

        (*carte) [i] = malloc( nbCol * sizeof( char ) );
        if ( (*carte) [i] == NULL )
        {
            return false;
        }
    }

    return true;

} // mallocCarte  ()

// Code sample, I've already got the others informations, now, I'd like to get the map
// On commence par reserver l'espace memoire reserve à la carte.
int res = mallocCarte( &problem->carte, problem->nb_ligne, problem->nb_col );

// Si l'allocation s'est mal passée, on renvoie un message
if ( res == false )
{
    exc.num_Exc = MALLOC_ERROR;
    exc.msg_Err = "Erreur lors de l'allocation mémoire de la carte";
    return exc;
}

printf( "Recuperation de la carte 2 ...%d %d\n", problem->nb_ligne,
        problem->nb_col );
int nbLi = 0;
int nbCol = 0;
while ( fgets( fromFile, 1, file ) != NULL && nbLi < problem->nb_ligne )
{
    if ( fromFile [0] == '\n' )
    {
        nbCol = 0;
        ++nbLi;
        continue;
    }

    if ( nbCol == problem->nb_col )
    {
        printf( "malformed input file!\n" );
        exit( -1 );
    }


    ( problem->carte ) [nbLi] [nbCol++] = fromFile [0];
}

It's been many days and I really don't know what to do... I'd be so greatful If someone could help me !

Thanks you

(Here is the source file where I take informations. First they are problem name, then some coordinates, and finally the map size. At the end of the file is the map https://dl.dropbox.com/u/56951442/map.txt )

Carvallegro
  • 1,241
  • 4
  • 16
  • 24
  • 4
    Does this even compile?.. I have some doubts about the `char **` line of the `struct` declaration. – Sergey Kalinichenko Apr 09 '13 at 17:08
  • 1
    You don't need to cast the return value of `malloc` in a C program. And `sizeof(char)` is `1`. – Carl Norum Apr 09 '13 at 17:09
  • If you want to return a 2d array via an out-parameter, the parameter needs type `char***`. Then your first assignment with look like `carte* = (char**)malloc( nbLigne * sizeof( char* ) );` – jpm Apr 09 '13 at 17:11
  • @jpm, no, not at all, it would look like `*carte = malloc(nbLigne * sizeof(**carte));` –  Apr 09 '13 at 17:14
  • @dasblinkenlight : yes, it compile (even with -Wall). – Carvallegro Apr 09 '13 at 17:14
  • Hum, I don't really get the carte* (or *carte), could you explain more please ? – Carvallegro Apr 09 '13 at 17:19
  • @H2CO3 Yes, you are correct, thanks for catching my egregious error. – jpm Apr 09 '13 at 17:25
  • @Hahuha You should read up on C operators if you don't recognize the pointer dereferencing operator... –  Apr 09 '13 at 17:30

2 Answers2

1

When you increment nbLi in main, you need to reset nbCol to zero. You are allowing the column to continue to increase infinitely and exceeding the size of your array.

Also, you should not cast malloc in C.

In addition, you should be passing &problem->carte into your allocation function...

// Function wich malloc the map
int mallocCarte( char *** carte, int nbLigne, int nbCol )
{
    *carte = malloc( nbLigne * sizeof( char* ) );
...
    (*carte)[i] = malloc( nbCol * sizeof( char ) );
...
}

main()
{
   ...
   int res = mallocCarte( &problem->carte, problem->nb_ligne, problem->nb_col );
   ...
}

You should probably add a test, too, to ensure you don't wander off the end of the column if your input file is illformed...

   if ( isspace( fromFile [0] ) )
   {
       nbCol = 0;
       ++nbLi;
       continue;
   }

   if( nbCol == problem->nb_col )
   {
       printf( "malformed input file!\n" );
       exit( -1 );
   }

Are you sure you mean to be using fgets( fromFile, 1, file ) ?? The below description implies that fgets() is always returning an empty string until the end of the file and fromFile[0] will always be '\0' until EOF. You should be using fgets( fromFile, 2, file )

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.

Community
  • 1
  • 1
K Scott Piel
  • 4,320
  • 14
  • 19
  • I put all of your suggestions in my code but it still doesn't work :/ Also, could you explain the ***char and *carte stuff ? I don't really get it – Carvallegro Apr 09 '13 at 17:24
  • You are allocating a char** and then you are allocating a char* to each element of the char** -- however, you want to RETURN that newly allocated pointer to the caller. That means that you have to write the new pointer into that argument and have the caller read that later... Think of it like this... if you pass an integer into a function, then the function can read and change that argument all it wants, but the caller will not see those changes because you passed a COPY of the integer. If you pass a POINTER to the integer, then modify its contents, the caller will see the changes. – K Scott Piel Apr 09 '13 at 17:30
  • Continuing... so... you want to pass a pointer TO the char** so you can store the char** in that pointer and the caller can see it. – K Scott Piel Apr 09 '13 at 17:31
  • That said... update the code to reflect the changes that you've made and I can look at it further... hard to say without being able to see your edited code. – K Scott Piel Apr 09 '13 at 17:33
  • I think you want `(*carte)[i] = malloc(nbCol);`. The subscript `[]` has higher precedence than the indirection `*`. – Daniel Fischer Apr 09 '13 at 17:36
  • You are correct... thanks for catching that. Edited accordingly. – K Scott Piel Apr 09 '13 at 17:38
  • I edited too (the code and the post). But... still a segmentation fault – Carvallegro Apr 09 '13 at 17:39
  • @Hahuha: You did not implement his suggestion in his first sentence. – jxh Apr 09 '13 at 17:45
  • Sorry, I did it but I forgot to write it in my post – Carvallegro Apr 09 '13 at 17:48
  • @Hahuha: Edit your post with the input you provide, and what you expect the carte to have in it after your input `fgets()` loop finishes. – jxh Apr 09 '13 at 17:50
  • What is the exact line that is is SEGSEGV on now? And how is fromFile declared? – K Scott Piel Apr 09 '13 at 17:50
  • Added a check to ensure that you aren't walking off the end of nbCol if your input file is illformed in my original reply – K Scott Piel Apr 09 '13 at 17:55
  • Did that and it seems that I'm going off the end of nbCol. I've just edited my code because of a mistake (that didn't solve the problem) – Carvallegro Apr 09 '13 at 19:01
  • okay -- so... back to the prior question... on exactly which line do you SIGSEGV? – K Scott Piel Apr 09 '13 at 19:04
  • Seems to be at line 80 here's my output : nbli : 0 nbcol : 80 malformed input file! – Carvallegro Apr 09 '13 at 19:08
  • Okay... see my latest edit to my answer. I think the issue you have remaining is the `fgets()` call. – K Scott Piel Apr 09 '13 at 19:10
  • YES ! Ho, thank you so much, I did'nt saw that... Well, it works perfectly now. Thx again – Carvallegro Apr 09 '13 at 19:13
  • /happydance -- glad we muddled our way through it. C'est bon! – K Scott Piel Apr 09 '13 at 19:17
  • Yeah ! C'est plus que bon, c'est parfait ;) – Carvallegro Apr 09 '13 at 19:29
-1

problem is a object of structure problem_t. It is not a pointer, you should access structure variable like

problem.carte,
problem.nb_ligne
problem.nb_col

I tried your code on my system. your code is working fine for me with your given map.txt. I just declared char fromFile[2]; While(fgets(fromFile,2,file) != NULL) {//printing file}. Its printing file properly for me.

surender8388
  • 474
  • 3
  • 12
  • If that were the case, the code would not compile at all... it's a given that problem was a pointer to a problem_t by the design of the code. – K Scott Piel Apr 09 '13 at 17:49
  • your code is working fine for me with your given map.txt. I just declared char fromFile[2]; While(fgets(fromFile,2,file) != NULL) {//printing file}. Its printing file properly for me. – surender8388 Apr 09 '13 at 19:49