-2

I don't understand why the if statement: &*accountslist[1] == &*unameslist[0] is true. What is going on here? Is the problem with my realloc? Also, when I make accountlist[1] = NULL it seems that unameslist[0] also gets set to null. This makes me think that for some reason they end up pointing to the same location.

int loadInfo( char*** accountslist, 
          char*** unameslist, 
          char*** passlist )
{
    FILE* account_file = fopen( ACCOUNTS_LOCATION, "r" );
    FILE* uname_file = fopen( UNAMES_LOCATION, "r" );
    FILE* pass_file = fopen( PASSWORDS_LOCATION, "r" );

    char* nextAccount;
    char* nextUname;
    char* nextPass;

    fileWithNum( account_file, &nextAccount );
    fileWithNum( uname_file, &nextUname );
    fileWithNum( pass_file, &nextPass );

    *accountslist = (char**) malloc( sizeof(char*) );
    *unameslist = (char**) malloc( sizeof(char*) );
    *passlist = (char**) malloc( sizeof(char*) );

    *accountslist[0] = nextAccount;
    *unameslist[0] = nextUname;
    *passlist[0] = nextPass;

    int num_accounts = 1;

    while( nextAccount != NULL && nextUname != NULL &&
           nextPass != NULL )
    {
        *accountslist = (char**)realloc( *accountslist, 
                                 (num_accounts + 1) * sizeof(char*));
        *unameslist = (char**)realloc( *unameslist,
                               (num_accounts + 1) * sizeof(char*));
        *passlist = (char**)realloc( *passlist,
                             (num_accounts + 1) * sizeof(char*));
        fileWithNum( account_file, &nextAccount );
        fileWithNum( uname_file, &nextUname );
        fileWithNum( pass_file, &nextPass );
        printf( "%s\n" , *unameslist[0] );
        *accountslist[1] = NULL;
        if( &*accountslist[1] == &*unameslist[0] ) printf("WHY??\n" );
        printf( "%s, %s, %s\n" , *accountslist[0], *unameslist[0], *passlist[0]);

        *accountslist[num_accounts] = nextAccount;
        *unameslist[num_accounts] = nextUname;
        *passlist[num_accounts] = nextPass;

        printf( "%s, %s, %s\n" , *accountslist[num_accounts],
            *unameslist[num_accounts], *passlist[num_accounts]);
        num_accounts++;
    }

    fclose( account_file );
    fclose( uname_file );
    fclose( pass_file );

    return num_accounts;
}
  • [Don't cast the result of malloc (and friends)](http://stackoverflow.com/q/605845). – Deduplicator Oct 18 '14 at 23:02
  • 2
    "Sorry my code isn't exactly formatted correctly"... Why didn't you correct it before posting then? – Deduplicator Oct 18 '14 at 23:05
  • I removed the casts, but that didn't help. I meant to say sorry if its not formatted correctly. I don't think there is an issue. – user2350896 Oct 18 '14 at 23:08
  • IMO it's impossible to answer this question. My bet is that something's wrong with `fileWithNum`, I think this is the only place that has any connection to all three arrays, of course trusting c libraries are doing they work properly. – luk32 Oct 18 '14 at 23:32

2 Answers2

0

&*accountslist[1] is equivalent to accountslist[1], and &*unameslist[0] is equivalent to unameslist[0], so you can rewrite that line as:

if( accountslist[1] == unameslist[0] ) printf("WHY??\n" );

The problem is that both accountslist and unameslist are pointers to your lists, i.e. they are of type char ***. They are not, themselves, arrays, so unameslist[0] is equivalent to *unameslist which is the address of your actual unameslist array, and accountslist[1] is actually out-of-bounds. Since that lands you in undefined behavior territory, you can't expect things to behave sensibly. Probably what's happening is that, prior to calling loadInfo(), you declared what unameslist points to immediately before what accountslist points to, so that accountslist[1] actually evaluates to the same address as *unameslist. This brief program demonstrates how this can happen:

#include <stdio.h>

void myfunc(char *** pp1, char *** pp2)
{
    /*  WARNING - undefined behavior ahead  */

    printf("pp1[1] is %p, pp2[0] is %p\n", (void *) pp1[1], (void *) pp2[0]);
}

int main(void)
{
    char ** p1 = (char **) 0xCC;
    char ** p2 = (char **) 0xFF;
    printf("p1 is %p, p2 is %p\n", (void *) p1, (void *) p2);
    printf("&p1 is %p, &p2 is %p\n", (void *) &p1, (void *) &p2);
    myfunc(&p2, &p1);
    return 0;
}

which, at least when I ran it, outputted:

paul@thoth:~/src/sandbox$ ./pdemo
p1 is 0xcc, p2 is 0xff
&p1 is 0x7fff8d138818, &p2 is 0x7fff8d138810
pp1[1] is 0xcc, pp2[0] is 0xcc
paul@thoth:~/src/sandbox$ 

and you can see how pp1[1] and pp2[0] are comparing equal due to the misuse of pointers. If you change pp1[1] to &*pp1[1] as you did, and likewise for pp2[0], you'll see that you get the exact same result since they're equivalent.

What you actually meant is probably something like:

if( (*accountslist)[1] == (*unameslist)[0] ) printf("WHY??\n" );

Note that [] binds more tightly than * does, so *accountslist[1] is equivalent to *(accountslist[1]), when what you actually want is to deference accountslist first, so you need (*accountslist)[1].

The short answer here is that you've got so much indirection you're confusing yourself and hugely misusing your pointers. As a result, practically none of your code is doing what you think it's doing. You should use some temporary variables to simplify and make it easier on yourself, e.g.:

char ** local_accounts_list = malloc(sizeof *local_accounts_list);

and then only at the end update your parameters with:

*accountslist = local_accounts_list;

You should also be checking the returns from malloc() and friends, fopen(), and any other function which might fail, which you never do. You can't be surprised when things don't work if you don't check for errors.

Crowman
  • 25,242
  • 5
  • 48
  • 56
  • The issue ended up being with trying to use the vars that were passed in instead of using a temporary var then assigning it to the parameters at the end. Thanks for the help. – user2350896 Oct 23 '14 at 23:17
0

Here is fileWithNum if anyone is interested

int fileWithNum( FILE* fptr, char** word )
{
  //finished fixing
  int size;
  char* temp = NULL;
  fscanf( fptr, "%d", &size );
  if( size == -1) 
  {
    return 0;
  }
  int character = 0;
  temp = (char*) malloc( (size + 1) * sizeof(char));
  int current;
  for( current = 0; current < size; current++ )
  {
      if( fscanf( fptr, "%d", &character ) != 1 )
      {
          printf( "fscanf error\n" );
      }
      //printf( "%c\n" , character );
      //printf( "%d\n" , current );
      temp[current] = character;
  }
  temp[size] = 0; //end of string char
  *word = temp;
  printf( "End of filewithnum\n" );
  return 0;
}