0

I want to create an array of 26 word arrays (to sort my lists of words by first letter) so I believe I allocated memory accordingly but when I try a test run and attempt to set a random word, "hi", to each spot which must have a word, it only works for the first 5 letters then returns a set fault. Pardon my code or description, I'm quite the beginner. HELP

Note: both my parameters are defined in external functions, wordArray is the array of words in a given text file, numWordsPerLetter is an integer array which holds the number of words that start with each letter of the alphabet.

char*** create_alphabetical_array(char** wordArray, int* numWordsPerLetter){

  char*** alphabeticalArrays;
  int i, j;

  alphabeticalArrays = malloc(sizeof(char**)*26);
  for (i = 0; i < 26; i++){
    printf("%d\n", numWordsPerLetter[i]+1);
    alphabeticalArrays[i] = malloc(sizeof(char*)*numWordsPerLetter[i]+1);
  }

  for (i = 0; i < 26; i++){
    for (j = 0; j < (numWordsPerLetter[i]+1); j++){
      printf("%d %d %d\n", i, j, numWordsPerLetter[i]+1); /* using to help debug */
      strcpy(alphabeticalArrays[i][j], "hi");
    }
  }

  return (alphabeticalArrays);
}

  • `malloc(26)` should be `malloc(26 * sizeof(char**))`. – Blaze Jan 27 '20 at 08:31
  • As for your problem don't forget that the size provided to [`malloc`](https://en.cppreference.com/w/c/memory/malloc) is the size in *bytes*, not something abstract as "elements". – Some programmer dude Jan 27 '20 at 08:32
  • @Blaze I had that before but it gave me a seg fault after the first iteration of the 2nd for loop, this way still gets me through 5 iterations before the seg fault – Nathan Drake Jan 27 '20 at 08:34
  • 2
    It looks like you forgot a `malloc` on the last dimension – Zelnes Jan 27 '20 at 08:34
  • regarding: `char*** alphabeticalArrays;` and similar statements: Please read [three star programmer](https://wiki.c2.com/?ThreeStarProgrammer) – user3629249 Jan 28 '20 at 17:37

1 Answers1

1

At least these 2 errors:

Wrong element size and wrong n. alphabeticalArrays[i] is a char **, so sizeof(int) is amiss. element_size * numWordsPerLetter[i]+1 should be element_size * (numWordsPerLetter[i]+1)

Better to use p = malloc(sizeof *p * n), then p = malloc(sizeof *(type-of p) * n). Easier to code right, review and maintain.

// alphabeticalArrays[i] = malloc(sizeof(int)*numWordsPerLetter[i]+1);
alphabeticalArrays[i] = malloc(sizeof alphabeticalArrays[i][0] * (numWordsPerLetter[i]+1));
//                             ^---Element size--------------^   ^-------------N--------^    

strcpy(alphabeticalArrays[i][j], "hi"); fails because alphabeticalArrays[i][j] is not assigned a pointer to allocated memory for the string "hi". @Zelnes

alphabeticalArrays[i][j] = malloc(strlen("hi") + 1);

Alternative: research strdup().


Robust code would also check if the allocations succeeded.

p = malloc(n);
if (p == NULL) Handle_Failure();
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • @NathanDrake Note the "At least this error:". The changes "works", it is just that code has additional problems. – chux - Reinstate Monica Jan 27 '20 at 09:05
  • I tried fixing the first problem using the format u recommended, would u say its appropriate? because I wish to allocate enough memory for the character arrays (arr[0][0], arr[0][1], etc.) of each letter array (arr[0], arr[1]) as given by the int array argument – Nathan Drake Jan 27 '20 at 09:10
  • @NathanDrake Yes. Also consider `alphabeticalArrays = malloc(sizeof(char**)*26);` --> `alphabeticalArrays = malloc(sizeof *alphabeticalArrays * 26);`. – chux - Reinstate Monica Jan 27 '20 at 09:14