N
Netocrat
(therefore a char ***) to scandir(). Presumably this function checksint getFileNames(char *directory, struct dirent **namelist)
{
int n, i;
n = scandir(directory, &namelist, 0, alphasort);
[snip]
On the last line of code above, you pass a pointer to 'namelist'
whether the pointed-to char ** is NULL or not, and if it is NULL, it
allocates the necessary memory. And also presumably, if the
pointed-to char ** is not NULL, it assumes that it points to valid
memory and uses it.
My understanding of the manpage on my implementation, backed up by my
reading of the source on my particular implementation, is that it
ignores any previously-pointed-to value and only stores to *namelist.
If that's true for the OP's platform too (which seems likely) then the
behaviour Jack guessed scandir() to have wasn't a contributor to the
problem. When you write *namelist above, I assume that you refer to the
parameter within scandir() - with type struct dirent ***, not the variable
passed by the caller as &namelist, with type struct dirent **.
[why are you calling 'struct dirent' 'char'?]
At the end you try to free a pointer that was not allocated.
You snipped this part, so I can't comment on it. According to the
manpage, you are supposed to free each member of *namelist [individual
struct dirent *] in turn, then free *namelist. The question is, what
differs between his two versions?
The answer that's turned up elsewhere in the thread is:
since namelist is being passed to getFileNames() as a struct dirent **,
the operations performed on it by scandir() are lost to the caller - it
needs to be passed as &namelist with getFileNames() taking a struct
dirent ***, in the same way that scandir() does.
The file-scope declaration set namelist to NULL, so that the user-defined
function to free it returned without problems, but when defined at
function scope in main(), given that it was (a) not initialised and (b)
the intended changes to the initial value were lost due to "passing by
value rather than reference", the user-defined function to free it was
operating on an invalid pointer. I've re-copied part of that function
below:
int freeFileNames(struct dirent **namelist, int entries)
{
int i;
if (namelist == NULL)
return 0;
else{
....
free(namelist);
....
free(namelist);
Both lines above invoke UB when namelist is defined at function-scope
in main since by this point it still hasn't been set.
namelist = NULL;
Redundant assignment since the function is operating on a different copy
of the pointer than the caller and is about to return anyhow.
}
return 1;
}