我opendir(.)用來打開我想要讀取的目錄的路徑。然后我使用readdir回圈來遍歷當前目錄中的所有檔案和目錄。然后我有一個char**串列來存盤 readdir 的內容。然后我進行排序**list以按字典順序排列。僅當我有一個長度超過 63 個字符的檔案時,我在對輸出進行排序時不斷收到溢位錯誤。為什么會這樣,我該如何解決?
void ls_short() {
char **list = NULL;
int count = 0;
DIR *dir;
struct dirent *rd;
dir = opendir(".");
// check to make sure that we can open the directory
if(dir == NULL){
perror("Not able to open The current directory.");
exit(EXIT_FAILURE);
}
while((rd = readdir(dir)) != NULL){
list = realloc(list, (count 1)*sizeof(*list));
list[count] = rd ->d_name;
count;
printf("%s\n",rd ->d_name);
}
printf("here we will print the list\n");
for (int i = 0; i < count;i ){
printf("%s\n",list[i]);
}
printf("Now we print the list in order and also get rid of . and .. directory\n");
list = realloc(list, (count 1)*sizeof(*list));
list[count] = "";
for (int i = 0; i < count - 1; i ){
for (int j = 0; j < count - i - 1; j ){
if (strcasecmp(list[j], list[j 1]) > 0) {
char* temp;
temp = (char*)calloc(count, sizeof(char)*256);
strcpy(temp, list[j]);
strcpy(list[j], list[j 1]);
strcpy(list[j 1], temp);
free(temp);
}
}
}
for (int i = 2; i < count;i ){
printf("%s\n",list[i]);
}
closedir(dir);
}
這是我得到的錯誤:

=================================================================
==43335==ERROR: AddressSanitizer: strcpy-param-overlap: memory ranges [0x6250000001fd,0x625000000220) and [0x62500000021d, 0x625000000240) overlap
#0 0x103ef03ef in wrap_strcpy 0xaf (libclang_rt.asan_osx_dynamic.dylib:x86_64h 0x433ef)
#1 0x103e9aa5d in ls_short ls.c:61
#2 0x103e9a5c4 in main ls.c:16
#3 0x7fff20379620 in start 0x0 (libdyld.dylib:x86_64 0x15620)
0x6250000001fd is located 253 bytes inside of 8192-byte region [0x625000000100,0x625000002100)
allocated by thread T0 here:
#0 0x103ef54c0 in wrap_malloc 0xa0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h 0x484c0)
#1 0x7fff2025b0fe in _readdir_unlocked$INODE64 0x6d (libsystem_c.dylib:x86_64 0x2a0fe)
#2 0x7fff2025b227 in readdir$INODE64 0x22 (libsystem_c.dylib:x86_64 0x2a227)
#3 0x103e9a6ad in ls_short ls.c:42
#4 0x103e9a5c4 in main ls.c:16
#5 0x7fff20379620 in start 0x0 (libdyld.dylib:x86_64 0x15620)
0x62500000021d is located 285 bytes inside of 8192-byte region [0x625000000100,0x625000002100)
allocated by thread T0 here:
#0 0x103ef54c0 in wrap_malloc 0xa0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h 0x484c0)
#1 0x7fff2025b0fe in _readdir_unlocked$INODE64 0x6d (libsystem_c.dylib:x86_64 0x2a0fe)
#2 0x7fff2025b227 in readdir$INODE64 0x22 (libsystem_c.dylib:x86_64 0x2a227)
#3 0x103e9a6ad in ls_short ls.c:42
#4 0x103e9a5c4 in main ls.c:16
#5 0x7fff20379620 in start 0x0 (libdyld.dylib:x86_64 0x15620)
SUMMARY: AddressSanitizer: strcpy-param-overlap (libclang_rt.asan_osx_dynamic.dylib:x86_64h 0x433ef) in wrap_strcpy 0xaf
==43335==ABORTING
Abort trap: 6
uj5u.com熱心網友回復:
readdir()有一個靜態緩沖區rd->d_name,每次呼叫時都會重用它,因此所有list元素都指向同一個字串。
當您將字串分配給陣列時,您應該制作它們的副本。
list[count] = strdup(rd->d_name);
并且在排序時,不要在字串之間復制名稱,只需交換指標即可。
if (strcasecmp(list[j], list[j 1]) > 0) {
char* temp;
temp = list[j];
list[j] = list[j 1];
list[j 1] = temp;
}
uj5u.com熱心網友回復:
while((rd = readdir(dir)) != NULL){
list = realloc(list, (count 1)*sizeof(*list));
list[count] = rd ->d_name;
count;
printf("%s\n",rd ->d_name);
}
您無處分配記憶體來保存您添加到串列中的字串。您分配記憶體來保存指向它的指標,僅此而已。
您需要更改list[count] = rd ->d_name;為:
list[count] = malloc(256);
strcpy(list[count], rd->d_name);
此外,排序時不需要為字串分配新記憶體。如果您已經為需要存盤的每個字串分配了記憶體(您必須這樣做或者您的串列已經損壞),為什么更改順序需要分配新的記憶體來保存字串?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/314591.html
上一篇:如何從最近一年過濾到一年前R
