我是 C++ 的新手,我有使用 C#、Objective-C 和 JavaScript 的经验。
目前我正在尝试编写一个函数,它接受一个路径并返回一个目录列表(该路径上的所有文件和文件夹)。我正在 Ubuntu 上执行此操作。
到目前为止,这是我的代码,老实说,我正在努力理解双指针语法及其实现的目标,但这是我的谷歌搜索引导我的地方......
int FileManager::GetDirectoryListing(char *path, dirent **directoryEntries)
{
// Debug output...
printf("Listing directory at %s\n", path);
// Allocate memory for the directory entries
*directoryEntries = new dirent[MAX_FILES];
// Open the path we were provided
DIR *directory = opendir(path);
// A counter of how many entries we have read
int entryCount = 0;
// Make sure we were able to open the directory
if(directory) {
printf("Successfully opened directory\n");
// Read the first entry in the directory
struct dirent *directoryEntry = readdir(directory);
// While we have a directory entry
while(directoryEntry) {
// Debug output...
printf("%s\n", directoryEntry->d_name);
// Copy the directory entry to the array of directory entries we will return
memcpy(&directoryEntries[entryCount], directoryEntry, sizeof(struct dirent));
// Increase our counter
++entryCount;
// Read the next directory
directoryEntry = readdir(directory);
}
// Close the directory
closedir(directory);
}
return entryCount;
}
然后我调用这个函数:
dirent *directoryEntries = NULL;
int numberOfEntries = FileManager::GetDirectoryListing(deviceRootPath, &directoryEntries);
printf("File Manager returned directory listing.\n");
for(int i = 0; i < numberOfEntries; ++i) {
printf("Looping through directory entries, at index: %i\n", i);
printf("%s\n", directoryEntries[i].d_name);
}
它在尝试访问 directoryEntries
中的第一个元素时被锁定即第一次循环。
我知道我不明白双指针在做什么,而且我对 directoryEntries
的结构没有清晰的认识。在调用 GetDirectoryListing
之后.
发生了什么以及遍历 directoryEntries
的正确方法是什么? ?
最佳答案
这一行
memcpy(&directoryEntries[entryCount], directoryEntry, sizeof(struct dirent));
应该是这样的:
memcpy(&(*directoryEntries)[entryCount], directoryEntry, sizeof(struct dirent));
或等同于:
memcpy(*directoryEntries + entryCount, directoryEntry, sizeof(struct dirent));
原因是directoryEntries
是指向数组的指针。在内存中,它看起来像这样:
+------------+
directoryEntries --> array_head --> | dirents[0] |
+------------+
| dirents[1] |
+------------+
| dirents[2] |
+------------+
| ... |
但您将其视为 directoryEntries
是一个指向数组的指针,它不是:
WRONG! +------------+
directoryEntries --> | dirents[0] |
+------------+
| dirents[1] |
+------------+
| ... |
因此,您将越界写入不属于您的内存,从而导致未定义的行为。
之所以需要额外的间接级别,是因为在 C 语言中,函数参数始终按值传递。为了修改参数,您需要传入一个指向原始值的指针,这就是您正在做的。您只需要记住,在处理该指针时,您有一个额外的间接级别。
如果您使用的是 C++ 而不是 C,则最好使用引用参数而不是指针,并且您还应该使用 std::vector<struct dirent>
.您无需担心额外的间接级别,内存管理会自动为您处理。
关于c++ - 从函数 C++ 返回数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7369818/