I wrote a function that scans a directory and copies all file names in it to a char**
that I pass as a parameter, I'm using dirent.h
to get the files in the directory, here is my main & the function:
int main(void)
{
char** files = 0;
int size = 0, i = 0;
size = scanDir(files, "C:\\Users\\user\\test");
for (i = 0; i < size; i++)
{
puts(files[i]);
free(files[i]);
}
free(files);
getchar();
return 0;
}
int scanDir(char** files, char* path)
{
int size = 0, i = 0;
DIR* dp = 0;
struct dirent* ep = 0;
files = (char**)malloc(sizeof(char*) * size);
dp = opendir(path);
if (dp != NULL)
{
while (ep = readdir(dp))
{
files = realloc(files, sizeof(char*) * ++size);
files[i] = (char*)malloc(sizeof(char) * (strlen(ep->d_name) + 1));
strcpy(files[i], ep->d_name);
i++;
}
(void)closedir(dp);
}
return size;
}
I'm using visual studio and during debugging files[i]
within scanDir
does contain the correct filename in each iteration of the while loop but in the for loop, it crashes and in the variable watch it says the it is "unable to read memory" under files
Why is that happening?
files
is passed by value, and so when scanDir
assigns to it and returns, the change doesn't propagate back to the caller.
I am afraid you need another level of indirection (char***
).
int main(void)
{
char** files = 0;
size = scanDir(&files, "C:\\Users\\user\\test");
...
}
int scanDir(char*** files, char* path)
{
...
*files = (char**)malloc(sizeof(char*) * size);
...
}
Alternatively, you could change the scanDir
signature to return
the newly allocated char**
pointer along with the size.