I'm having some trouble with the code below it sould take the path to a folder as input (in my case "pack") and put the paths to each .wav file it can find in the folder or in subfolders into an array of string.
The code you can see below crashes.
Before asking you guys some help I've search by myself and the crash seems to append while in the second subfolder when trying to realloc for the first file of that folder
The folder structure I'm testing with goes like this :
pack
├── _subfolder1
| ├── wavefile1.wav
| ├── wavefile2.wav
| └── wavefile3.wav
├── _subfolder2
| └── wavefile4.wav
├── _subfolder3
| ├── wavefile5.wav
| └── wavefile6.wav
code :
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
void find_dir_content(char* path, char** filepathlist, int* size)
{
DIR* d = opendir(path);
if(d == NULL)
return;
struct dirent* dir;
while((dir = readdir(d)) != NULL)
{
int isdir = 0;
DIR* tmp;
char f_path[255];
sprintf(f_path, "%s/%s", path, dir->d_name);
if((tmp = opendir(f_path))) {
closedir(tmp);
isdir = 1;
}
if(!isdir) {
char *dot = strrchr(dir->d_name, '.');
if (dot && !strcmp(dot, ".wav")){
char** tmp = realloc(filepathlist, sizeof(char*) * ((*size) + 1));
if (tmp == NULL)
{
return;
}
else
{
filepathlist = tmp;
}
char d_path[256];
sprintf(d_path, "%s/%s", path, dir->d_name);
filepathlist[*size] = d_path;
//printf("%d : %s\n", *size, filepathlist[*size]);
(*size)++;
}
}
else if(isdir && strcmp(dir->d_name, ".") != 0 &&
strcmp(dir->d_name, "..") != 0)
{
char d_path[256];
sprintf(d_path, "%s/%s", path, dir->d_name);
//printf("%s\n", d_path);
find_dir_content(d_path, filepathlist, size);
}
}
closedir(d);
}
int main(int argc, char** argv)
{
int sizefilepathlist = 0;
char** filepathlist = (char**) malloc(0*sizeof(char*));
find_dir_content("pack", filepathlist, &sizefilepathlist);
for(int i = 0; i< sizefilepathlist; i++){
printf("%s", filepathlist[i]);
}
return 0;
}
Edit: I'm on windows, I use codelite with minGW(gcc), and there is no error message, windows just gives me the old "has stopped working" error.
As pointed out by @unwind in the comments:
You're storing the address of a local variable. That will get you undefined behavior. You must dynamically allocate room for the path itself, not just the pointer to it.
The smallest change would be to change the line:
filepathlist[*size] = d_path;
to
filepathlist[*size] = strdup(d_path); // d_path will go out of scope - copy the string to dynamically allocated memory.
Make sure you #include <string.h>
to get the prototype for strdup
.
EDIT:
Another problem is that when you realloc(filepathlist)
the variable in main
still points to the old location. This can be fixed by letting find_dir_content
return the current location of filepathlist
:
char **filepathlist(...) {
...
return filepathlist;
}
and in main:
filepathlist = find_dir_content("pack", filepathlist, &sizefilepathlist);