使用 SDL_strdup 和类似方法获取文件名时出现问题
Problems grabbing file names using SDL_strdup and similar
我正在尝试使用 SDL2 创建程序。
在代码的某个部分,我正在编写函数来获取给定目录路径中所有存在文件的名称(并将它们保存在内存中),以便在另一个函数中,我可以检查最后一个指定文件是否存在检查目录的那一刻。
我正在使用 dirent.h
来满足我的需要,但我 运行 遇到了一些问题:
- 所有文件都被
readdir()
正确捕获(无一例外),但是在使用 SDL_strdup()
(代码如下)。
- 我正在使用
SDL_malloc()
/SDL_realloc()
/SDL_strdup()
尽可能跨平台,以避免在移植代码时出现问题(因为我读过 strdup 是't C 标准)。
这是我的代码:
typedef struct FileList {
char **files;
size_t num;
} FileList;
FileList *GetFileList(const char *path){
struct dirent *dp = NULL;
DIR *dir = NULL;
size_t i = 0;
FileList *filelist = SDL_malloc(sizeof(FileList)); /* changing this to a calloc doesn't help */
/* Check if filelist == NULL */
filelist->files = NULL;
dir = opendir(path);
/* Check if dir == NULL */
while ((dp = readdir(dir))){
if (dp->d_name[0] == '.'){
continue; /* skip self, parent and all files starting with . */
}
printf("Copying: %s\n", dp->d_name); /* Always show the name of each file */
filelist->files = SDL_realloc(filelist->files, ++i);
filelist->files[i-1] = SDL_strdup(dp->d_name);
printf("Copied: %s\n\n", filelist->files[i-1]); /* Varies: either shows the file's name, either gives me plain gibberish or just nothing */
}
filelist->num = i;
closedir(dir);
return filelist;
}
输出不同。当它没有崩溃时,我要么正确地复制了所有文件名,要么我复制了其中的大部分文件名,其中一些不包含任何内容或只是乱码(如评论所述);如果它确实崩溃,有时我在使用 SDL_strdup()
时会遇到段错误,其他时候我会在使用 closedir()
.
时遇到段错误
我什至考虑过将 SDL_realloc()
场景与初始内存分配 filelist->files
交换,方法是给它文件数量(多亏了另一个函数),但我遇到了同样的问题。
任何将我的编码风格更改为更具防御性的风格的建议(因为我确实相信这种风格相当危险)将不胜感激,尽管我已为这种情况尽了我所能。我目前正在使用内置 gcc Apple LLVM 6.0 (clang-600.0.56) 开发 Mac OS X。
你需要 space 作为指针,sizeof(char *) != 1
所以
filelist->files = (char**) SDL_realloc(filelist->files, ++i);
需要
filelist->files = SDL_realloc(filelist->files, ++i * sizeof(char *));
但这实际上是个坏主意,因为 SDL_realloc
可以 return NULL
在这种情况下,您将失去对原始指针的引用,所以这样做的一个好方法是
void *ptr;
ptr = SDL_realloc(filelist->files, ++i * sizeof(char *));
if (ptr == NULL)
handleThisErrorAndDoNotContinue();
filelist->files = ptr;
并且总是检查分配器函数,如果它们 returned NULL
,因为你无法控制你试图读取的数据的大小,你可以 运行内存至少在理论上,所以你应该通过检查这些函数的成功来确保你的代码安全。
我正在尝试使用 SDL2 创建程序。
在代码的某个部分,我正在编写函数来获取给定目录路径中所有存在文件的名称(并将它们保存在内存中),以便在另一个函数中,我可以检查最后一个指定文件是否存在检查目录的那一刻。
我正在使用 dirent.h
来满足我的需要,但我 运行 遇到了一些问题:
- 所有文件都被
readdir()
正确捕获(无一例外),但是在使用SDL_strdup()
(代码如下)。 - 我正在使用
SDL_malloc()
/SDL_realloc()
/SDL_strdup()
尽可能跨平台,以避免在移植代码时出现问题(因为我读过 strdup 是't C 标准)。
这是我的代码:
typedef struct FileList {
char **files;
size_t num;
} FileList;
FileList *GetFileList(const char *path){
struct dirent *dp = NULL;
DIR *dir = NULL;
size_t i = 0;
FileList *filelist = SDL_malloc(sizeof(FileList)); /* changing this to a calloc doesn't help */
/* Check if filelist == NULL */
filelist->files = NULL;
dir = opendir(path);
/* Check if dir == NULL */
while ((dp = readdir(dir))){
if (dp->d_name[0] == '.'){
continue; /* skip self, parent and all files starting with . */
}
printf("Copying: %s\n", dp->d_name); /* Always show the name of each file */
filelist->files = SDL_realloc(filelist->files, ++i);
filelist->files[i-1] = SDL_strdup(dp->d_name);
printf("Copied: %s\n\n", filelist->files[i-1]); /* Varies: either shows the file's name, either gives me plain gibberish or just nothing */
}
filelist->num = i;
closedir(dir);
return filelist;
}
输出不同。当它没有崩溃时,我要么正确地复制了所有文件名,要么我复制了其中的大部分文件名,其中一些不包含任何内容或只是乱码(如评论所述);如果它确实崩溃,有时我在使用 SDL_strdup()
时会遇到段错误,其他时候我会在使用 closedir()
.
我什至考虑过将 SDL_realloc()
场景与初始内存分配 filelist->files
交换,方法是给它文件数量(多亏了另一个函数),但我遇到了同样的问题。
任何将我的编码风格更改为更具防御性的风格的建议(因为我确实相信这种风格相当危险)将不胜感激,尽管我已为这种情况尽了我所能。我目前正在使用内置 gcc Apple LLVM 6.0 (clang-600.0.56) 开发 Mac OS X。
你需要 space 作为指针,sizeof(char *) != 1
所以
filelist->files = (char**) SDL_realloc(filelist->files, ++i);
需要
filelist->files = SDL_realloc(filelist->files, ++i * sizeof(char *));
但这实际上是个坏主意,因为 SDL_realloc
可以 return NULL
在这种情况下,您将失去对原始指针的引用,所以这样做的一个好方法是
void *ptr;
ptr = SDL_realloc(filelist->files, ++i * sizeof(char *));
if (ptr == NULL)
handleThisErrorAndDoNotContinue();
filelist->files = ptr;
并且总是检查分配器函数,如果它们 returned NULL
,因为你无法控制你试图读取的数据的大小,你可以 运行内存至少在理论上,所以你应该通过检查这些函数的成功来确保你的代码安全。