Pen275 Pen275 - 1 month ago 6
C Question

C - fscanf works with characters pointers but not double character pointers?

I have this code:

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

int main(void)
{
char **string = malloc(sizeof(char) * 20);
FILE *fp = fopen("input.txt", "r");
fscanf(fp, "%s", *string);

printf("%s\n", *string);

}


This code generates a segmentation fault. However, if I change
**string
to be a single character pointer and change the
*string
s to
string
it works. Why is this? And how can I use fscanf with arrays of pointers?

Thanks.

Answer
char **string = malloc(sizeof(char*)); // Pointer to pointer --> Alloc size of a POINTER
*string = malloc(sizeof(char) * 20); // Dereference and then you can malloc chars

When you allocate a pointer to a pointer, you allocate the size of the pointer first. You then dereference the variable and allocate the size of the contents of the pointer, in this case, the number of characters that it points to.

Also, your usage of fscanf is not only unsafe, but totally unneccessary as well.

Use fgets instead:

fgets( *string, 20, fp );

If you want to allocate an array of pointers to chars, then multiply the sizeof char* by the number entries when allocating the pointer-to-pointer. You must also use a for loop to allocate memory for each character pointer as shown above.

// Example code
char **string = malloc(sizeof(char*) * 10); // Allocates an array of 10 character pointers
if (string == 0) {
  fprintf(stderr, "Memory allocation failed.");
  exit(1);
}
int i = 0;
FILE *fp = fopen("input.txt", "r");
if (fp == 0) {
  fprintf(stderr, "Couldn't open input.txt for reading.");
  exit(1);
}
for (; i < 10; ++i) {
  string[i] = malloc(sizeof(char) * 20); // For each char pointer, allocates enough memory for 20 characters
  if (string[i] == 0) {
    fprintf(stderr, "Memory allocation failed.");
    exit(1);
  }
  fgets(string[i], 20, fp);
  printf("%s\n", string[i]);
}