使用 strcpy 和 strcat 时堆栈粉碎
Stack Smashing while using strcpy and strcat
我已经尝试调试了一段时间,仍然无法弄清楚为什么会导致堆栈粉碎错误(我认为错误代码是 6,或者中止。本质上这个函数需要一个目录,打开一个文件,然后将该文件放入一个函数中,以便它可以使用该文件,然后输出它通过该函数的次数。
int map(char* dir, void* results, size_t size, int (*act)(FILE* f, void* res, char* fn))
{
printf("%s\n", dir);
char copyDirectory[strlen(dir)+1];
//adds the slash
strcpy(copyDirectory, dir);
strcat(copyDirectory, "/");
//before the psuedocode, get all the files in the directory
int numFiles = nfiles(copyDirectory);
DIR* directory = opendir(copyDirectory);
//if there aren't any files, then we exit
if(numFiles == 0)
{
closedir(directory);
return -1;
}
//reads the file from the directory
struct dirent* readFile = readdir(directory);
int output = 0;
while(readFile!=NULL)
{
if(readFile->d_type==DT_REG)
{
//step 2: obtain filepath
char* fileName = readFile->d_name;
int filePathLength = strlen(dir) + strlen(fileName) + 1;//add one for the slash
char filePath[filePathLength];
memset(filePath, 0, filePathLength); //allocat ememory for file path
strcpy(filePath, strcat(dir, fileName));
//step 3: open file
FILE* file = fopen(filePath, "r");
//if the file is unreachable, exit
if(file==NULL)
{
closedir(directory);
return -1;
}
//step 4: perform some action and store result
strcpy(dir, copyDirectory);
act(file, results, fileName);
//step 5: close file
fclose(file);
//to go through loop: increment the readFile
++output;
}
readFile = readdir(directory);
}
closedir(directory);
return output;
}
地图函数与示例。
int map(char* dir, void* results, size_t size, int (*act)(FILE* f, void* res, char* fn))
{
char* copyDirectory = strdup(dir);
DIR* directory = opendir(dir);
int output = 0;
struct dirent* readFile = readdir(directory);
while(readFile!=NULL)
{
if(readFile->d_type==DT_REG)
{
//step 2: obtain filepath
char* fileName = readFile->d_name;
int filePathLength = strlen(dir) + strlen(fileName) +2;//add one for the slash
char filePath[filePathLength+1];
memset(filePath, 0, filePathLength); //allocat ememory for file path
strcpy(filePath, strcat(dir, fileName));
//step 3: open file
FILE* file = fopen(filePath, "r");
//if the file is unreachable, exit
if(file==NULL)
{
closedir(directory);
return -1;
}
//step 4: perform some action and store result
strcpy(dir, copyDirectory);
act(file, results, fileName);
//step 5: close file
fclose(file);
//to go through loop: increment the readFile
++output;
}
readFile = readdir(directory);
}
closedir(directory);
return output;
}
//Sample Map function action: Print file contents to stdout and returns the number bytes in the file.
int cat(FILE* f, void* res, char* filename) {
char c;
int n = 0;
printf("%s\n", filename);
while((c = fgetc(f)) != EOF) {
printf("%c", c);
n++;
}
printf("\n");
return n;
}
int main(int argc, char const *argv[])
{
char directory[]= "../rsrc/ana_light/";
size_t size = 100;
void* results[500];
int mapCat = map(directory, results, size, cat);
printf("The value of map is %d.\n", mapCat);
return EXIT_SUCCESS;
}
失败的地方是在它执行并打印到输出之后。该函数应打印出您拥有的文件的内容。目录列表末尾需要有一个“/”。目前它打印文件内容并以读取的文件数的值退出,但在退出并出现堆栈粉碎错误后它会消失。
EDIT1:编辑代码以反映我所做的更改。
EDIT2:我认为是根据 MCVE 标准完成的?应该 运行 如果我没记错的话。
第一个问题:改变
char copyDirectory[strlen(dir)+1];
到
char copyDirectory[strlen(dir)+2];
第二题:改变
char filePath[filePathLength];
到
char filePath[filePathLength+1];
第三个问题(初读时似乎没有变化):
//strcpy(copyDirectory, dir);
strcat(copyDirectory, dir);
注释掉的代码是正确的:
strcpy(copyDirectory, dir);
您忘记了尾随空字符的空格。
第四个问题:你忘了处理opendir failing
第五题:这段代码错误:
memset(filePath, 0, filePathLength); //allocat ememory for file path
strcpy(filePath, strcat(dir, fileName));
更改为:
strcpy(filePath, copyDirectory);
strcat(filePath, fileName);
不要在此处写入您的输入变量。这是一个非常糟糕的主意。
在撤消 copyDirectory 的(泄漏的)strdup 并将您非常创新的本地缓冲区 放回 之后,我能够将代码 运行 完成。
我已经尝试调试了一段时间,仍然无法弄清楚为什么会导致堆栈粉碎错误(我认为错误代码是 6,或者中止。本质上这个函数需要一个目录,打开一个文件,然后将该文件放入一个函数中,以便它可以使用该文件,然后输出它通过该函数的次数。
int map(char* dir, void* results, size_t size, int (*act)(FILE* f, void* res, char* fn))
{
printf("%s\n", dir);
char copyDirectory[strlen(dir)+1];
//adds the slash
strcpy(copyDirectory, dir);
strcat(copyDirectory, "/");
//before the psuedocode, get all the files in the directory
int numFiles = nfiles(copyDirectory);
DIR* directory = opendir(copyDirectory);
//if there aren't any files, then we exit
if(numFiles == 0)
{
closedir(directory);
return -1;
}
//reads the file from the directory
struct dirent* readFile = readdir(directory);
int output = 0;
while(readFile!=NULL)
{
if(readFile->d_type==DT_REG)
{
//step 2: obtain filepath
char* fileName = readFile->d_name;
int filePathLength = strlen(dir) + strlen(fileName) + 1;//add one for the slash
char filePath[filePathLength];
memset(filePath, 0, filePathLength); //allocat ememory for file path
strcpy(filePath, strcat(dir, fileName));
//step 3: open file
FILE* file = fopen(filePath, "r");
//if the file is unreachable, exit
if(file==NULL)
{
closedir(directory);
return -1;
}
//step 4: perform some action and store result
strcpy(dir, copyDirectory);
act(file, results, fileName);
//step 5: close file
fclose(file);
//to go through loop: increment the readFile
++output;
}
readFile = readdir(directory);
}
closedir(directory);
return output;
}
地图函数与示例。
int map(char* dir, void* results, size_t size, int (*act)(FILE* f, void* res, char* fn))
{
char* copyDirectory = strdup(dir);
DIR* directory = opendir(dir);
int output = 0;
struct dirent* readFile = readdir(directory);
while(readFile!=NULL)
{
if(readFile->d_type==DT_REG)
{
//step 2: obtain filepath
char* fileName = readFile->d_name;
int filePathLength = strlen(dir) + strlen(fileName) +2;//add one for the slash
char filePath[filePathLength+1];
memset(filePath, 0, filePathLength); //allocat ememory for file path
strcpy(filePath, strcat(dir, fileName));
//step 3: open file
FILE* file = fopen(filePath, "r");
//if the file is unreachable, exit
if(file==NULL)
{
closedir(directory);
return -1;
}
//step 4: perform some action and store result
strcpy(dir, copyDirectory);
act(file, results, fileName);
//step 5: close file
fclose(file);
//to go through loop: increment the readFile
++output;
}
readFile = readdir(directory);
}
closedir(directory);
return output;
}
//Sample Map function action: Print file contents to stdout and returns the number bytes in the file.
int cat(FILE* f, void* res, char* filename) {
char c;
int n = 0;
printf("%s\n", filename);
while((c = fgetc(f)) != EOF) {
printf("%c", c);
n++;
}
printf("\n");
return n;
}
int main(int argc, char const *argv[])
{
char directory[]= "../rsrc/ana_light/";
size_t size = 100;
void* results[500];
int mapCat = map(directory, results, size, cat);
printf("The value of map is %d.\n", mapCat);
return EXIT_SUCCESS;
}
失败的地方是在它执行并打印到输出之后。该函数应打印出您拥有的文件的内容。目录列表末尾需要有一个“/”。目前它打印文件内容并以读取的文件数的值退出,但在退出并出现堆栈粉碎错误后它会消失。
EDIT1:编辑代码以反映我所做的更改。
EDIT2:我认为是根据 MCVE 标准完成的?应该 运行 如果我没记错的话。
第一个问题:改变
char copyDirectory[strlen(dir)+1];
到
char copyDirectory[strlen(dir)+2];
第二题:改变
char filePath[filePathLength];
到
char filePath[filePathLength+1];
第三个问题(初读时似乎没有变化):
//strcpy(copyDirectory, dir);
strcat(copyDirectory, dir);
注释掉的代码是正确的:
strcpy(copyDirectory, dir);
您忘记了尾随空字符的空格。
第四个问题:你忘了处理opendir failing
第五题:这段代码错误:
memset(filePath, 0, filePathLength); //allocat ememory for file path
strcpy(filePath, strcat(dir, fileName));
更改为:
strcpy(filePath, copyDirectory);
strcat(filePath, fileName);
不要在此处写入您的输入变量。这是一个非常糟糕的主意。
在撤消 copyDirectory 的(泄漏的)strdup 并将您非常创新的本地缓冲区 放回 之后,我能够将代码 运行 完成。