在函数内部声明 char 数组时出现分段错误
Segmentation fault when char array is declared inside function
今天我在编写一些 C/C++ 代码时遇到了一个奇怪的行为,我想知道解释是什么。
这里有两个代码片段显示了相同的函数,第一个代码片段在函数外部声明了静态数组 "char comp[BUFFLEN];",而第二个代码片段在函数内部声明。 BUFFLEN 定义为尺寸 1024。
我指的奇怪行为是这样的:第一个函数运行完美并提供预期的输出,而第二个函数因段错误而崩溃。
我知道错误在哪里 - 我在复制之前没有为 k 分配内存(显然,在修复之后,两种变体都运行良好),但我希望有人能告诉我发生了什么以及为什么我没有得到第一个错误一。谢谢!
char comp[BUFFLEN];
void gen_struct(char* path){
char pathc[BUFFLEN];
memset(comp, 0, BUFFLEN);
comp[0] = '[=10=]';
strcpy(pathc, path);
cout << path << endl;
char* p = strtok(pathc, "/");
char* k;
strcpy(k,p);
do{
if(p == NULL){
cout << "Write " << k << " to disk\n";
break;
}
sprintf(comp, "%s/%s", comp, p);
// strcat(comp, p);
cout << "Making directory: " << comp << endl;
// Sysops::mkdir(comp);
strcpy(k,p);
p = strtok(NULL, "/");
}while(true);
}
void gen_struct(char* path){
char pathc[BUFFLEN];
char comp[BUFFLEN];
memset(comp, 0, BUFFLEN);
comp[0] = '[=10=]';
strcpy(pathc, path);
cout << path << endl;
char* p = strtok(pathc, "/");
char* k;
strcpy(k,p);
do{
if(p == NULL){
cout << "Write " << k << " to disk\n";
break;
}
sprintf(comp, "%s/%s", comp, p);
// strcat(comp, p);
cout << "Making directory: " << comp << endl;
// Sysops::mkdir(comp);
strcpy(k,p);
p = strtok(NULL, "/");
}while(true);
}
抱歉,如果标题不合适,我试着想一些实际上有人会 google 的东西。
只看你的代码而不详细检查就会发现一个明显的问题
您不检查 strtok()
是否返回 NULL
,取消引用 NULL
指针是 未定义的行为,故障线是
char* p = strtok(pathc, "/");
然后你strcpy()
“令牌”。
您没有为 k
分配 space,因此 k
未初始化并且包含垃圾,试图写入“地址”它指向的是未定义的行为。
这个问题可能会在这一行出现
strcpy(k, p)
达到 时,无法预测程序的行为,但是当变量 declared/defined 在不同的地方时,您可以预期它的行为会有所不同,因为程序布局会有所不同并且行为通常取决于此。
你也在工作,就好像它是一个 c 程序,虽然它显然是一个 c++ 程序,c++ 程序员不会使用 strtok()
和 char
指针来处理字符串,c 程序员几乎没有做它并且必须处理这些事情,因为你使用的是 c++ 编译器我建议 std::string
你可以拆分字符串,不需要担心分配内存等问题
今天我在编写一些 C/C++ 代码时遇到了一个奇怪的行为,我想知道解释是什么。
这里有两个代码片段显示了相同的函数,第一个代码片段在函数外部声明了静态数组 "char comp[BUFFLEN];",而第二个代码片段在函数内部声明。 BUFFLEN 定义为尺寸 1024。 我指的奇怪行为是这样的:第一个函数运行完美并提供预期的输出,而第二个函数因段错误而崩溃。 我知道错误在哪里 - 我在复制之前没有为 k 分配内存(显然,在修复之后,两种变体都运行良好),但我希望有人能告诉我发生了什么以及为什么我没有得到第一个错误一。谢谢!
char comp[BUFFLEN];
void gen_struct(char* path){
char pathc[BUFFLEN];
memset(comp, 0, BUFFLEN);
comp[0] = '[=10=]';
strcpy(pathc, path);
cout << path << endl;
char* p = strtok(pathc, "/");
char* k;
strcpy(k,p);
do{
if(p == NULL){
cout << "Write " << k << " to disk\n";
break;
}
sprintf(comp, "%s/%s", comp, p);
// strcat(comp, p);
cout << "Making directory: " << comp << endl;
// Sysops::mkdir(comp);
strcpy(k,p);
p = strtok(NULL, "/");
}while(true);
}
void gen_struct(char* path){
char pathc[BUFFLEN];
char comp[BUFFLEN];
memset(comp, 0, BUFFLEN);
comp[0] = '[=10=]';
strcpy(pathc, path);
cout << path << endl;
char* p = strtok(pathc, "/");
char* k;
strcpy(k,p);
do{
if(p == NULL){
cout << "Write " << k << " to disk\n";
break;
}
sprintf(comp, "%s/%s", comp, p);
// strcat(comp, p);
cout << "Making directory: " << comp << endl;
// Sysops::mkdir(comp);
strcpy(k,p);
p = strtok(NULL, "/");
}while(true);
}
抱歉,如果标题不合适,我试着想一些实际上有人会 google 的东西。
只看你的代码而不详细检查就会发现一个明显的问题
您不检查
strtok()
是否返回NULL
,取消引用NULL
指针是 未定义的行为,故障线是char* p = strtok(pathc, "/");
然后你
strcpy()
“令牌”。您没有为
k
分配 space,因此k
未初始化并且包含垃圾,试图写入“地址”它指向的是未定义的行为。
这个问题可能会在这一行出现
strcpy(k, p)
达到 时,无法预测程序的行为,但是当变量 declared/defined 在不同的地方时,您可以预期它的行为会有所不同,因为程序布局会有所不同并且行为通常取决于此。
你也在工作,就好像它是一个 c 程序,虽然它显然是一个 c++ 程序,c++ 程序员不会使用 strtok()
和 char
指针来处理字符串,c 程序员几乎没有做它并且必须处理这些事情,因为你使用的是 c++ 编译器我建议 std::string
你可以拆分字符串,不需要担心分配内存等问题