tags:

views:

76

answers:

3

I am making a function that turns a list of words into an array to be used by other functions, but somehow I'm overwriting previous words. I check the memory address' and they seem different, but when I recheck once I'm done importing the words, they are all the same.

static char **array;

//takes the name of a data file and reads it into an array
static void InitDictionary(char *fileName){
  //slide 36, chap 3
  FILE *file;
  int count,i;
  char dummy[30];
  file = fopen(fileName, "r");

  while( fscanf(file, "%s", dummy) == 1 ){//counting at first
    count++;
  }
  fclose(file);

  array = (char**) malloc(count * sizeof(char*) );
  count = 0;
  file = fopen(fileName, "r");
    while( fscanf(file, "%s", dummy) == 1 ){//now putting values in array
      char newEntry[30];
      strcpy(newEntry,dummy);
      array[count] = newEntry;
      printf("%d - %s : %p \n",count, array[count], &array[count]);

      count++;
    }
  fclose(file);

  for(i=0;i<count;i++)
    printf("%d - %s : %p\n",i, array[i], &array[count] );


}

Thanks

+5  A: 

You need to allocate new memory for newEntry each time through the while loop. You're currently storing a pointer to the single newEntry buffer multiple times.

When you said you've checked the addresses, what address did you check specifically?

And actually, what's probably technically happening here is that you're storing references to a variable that goes out of scope after each iteration of the while loop. Since it is out of scope, the compiler is then free to reuse that stack memory which it does for the next iteration of the loop.

A: 

One problem I see, count isn't initialized and you're using it in your malloc.

Gary
+2  A: 

user470379 is correct, you aren't allocating space for each new word. One possible fix is to replace the three lines:

char newEntry[30];
strcpy(newEntry,dummy);
array[count] = newEntry;

with

array[count] = strdup(dummy);
Blastfurnace
Just be sure to free the memory when done -- strdup mallocs space for the new copy that you must free.
@user470379 - Exactly, doing individual strdup's is a lot of fiddly resource management. It might be simpler and faster to read the entire file into a single allocated block of memory and then index and NUL terminate each word in place. Then the whole thing can later be freed at once.
Blastfurnace