I am using a tutorial to make a piece of code that reads a directory and dynamically populates an array with the files names.
Firstly, the code below does not work, because it populates the entire array with just one file name - the very last file name in the directory. Secondly, I am having trouble understanding some pieces of it. After the code, I am including a list of questions.
char** directory_string_array(char* directory){
DIR *dp;
struct dirent *ep;
dp = opendir(directory);
char* current_directory;
char **string_array = NULL;
int i = 0, strcount = 0;
if (dp !=NULL){
while (ep = readdir (dp)){
//pointer to char array which contains name of current file
current_directory = ep->d_name;
//allocate additional memory to string_array
string_array = (char**) realloc(string_array, (strcount+1) * sizeof(char*));
string_array[strcount++] = current_directory;
}
(void) closedir(dp);
} else{
perror("Couldn't open the directory");
}
//print the array to check it
for(i = 0; i <strcount; i++){
printf("strarray[%d] == %s\n", i, string_array[i]);
}
//free memory (this will later be outsourced to another file - I know that this will free memory from the thing I am trying to return
for(i = 0; i < strcount; i++){
free(string_array[i]);
}
free(string_array);
return string_array;
}
The resulting array should be:
Array = {".", "..", "File1", "File2"}
But instead it is:
Array = {"File2", "File2", "File2", "File2"}
Question 1:
char **string_array = NULL;
I noticed that this "pointer to pointer" concept is used a lot, and I think I am misunderstanding why/how it is used. I thought that a pointer to anything is just a pointer (a memory chunk which holds an address to something). Why do we care that this particular pointer points to another pointer? Is this just notation or does the compiler treat ** different from *?
Question 2:
string_array = (char**) realloc(string_array, (strcount+1) * sizeof(char*));
So here we allocate an additional block of memory of same size as char* (I take it that it is of the same size as char**). However, why do we not allocate memory for individual members of the string array? So why do we not use this line of code next, for example:
string_array[0] = malloc(sizeof(char*));
mallocfor the individual string elements as you go through results ofreaddir. You should also assign results ofreallocto a temporary, not to thestring_array, to avoid writing over aNULLon out-of-memory errors.void *as returned bymalloc& friends!