[英]Segmentation fault with concatenation of two strings
我正在尝试构建由 3 个首字母和 3 个最终数字组成的字母数字字符串,并将它们保存在.txt文件中。 我写了这个:
int i = 0,
j = 0;
char name_cpu[8],
array_numbers_final[8],
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
问题在于,在第一个外部for循环中,它正确打印了一个“AAA000”形式的字符串。 在第二个 for 循环中,它进入分段错误。 谁能告诉我我做错了什么以及在哪里做错了?
编辑:一个最小的可重现示例是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void){
FILE *list_cpu = NULL;
int i = 0,
number_cpu = 3,
j = 0;
char name_cpu[8] = {0},
array_numbers_final[8] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
list_cpu = fopen("list_cpu.txt", "w");
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
return(0);
}
如果number_cpu等于 1 它可以工作。 但如果它高于 1,则程序进入分段错误。
回答对 OP 的新编辑
对 OP 的编辑包括初始化变量,以解决原始代码中未定义行为的一些实例,但缓冲区溢出问题仍然存在于以下部分:
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(list_cpu, "%s \n", name_cpu);
}
fclose(list_cpu);
其中name_cpu
用 8 个字符定义: char name_cpu[8] = {0}
“如果 number_cpu 等于 1 它可以工作。但如果它高于 1,则程序进入分段错误。”...
在外循环的第一次迭代之后,包括一个strcat
name_cpu
和list_cpu
, char name_cpu
填充有 6 个新字符和\0
在剩余位置。 例如:
//example
|S|J|P|Y|E|P|\0|\0| //
该错误发生在strcat()
语句的外部循环的第二次迭代结束时。 内部循环重新填充了name_cpu
的前三个位置,例如:
//first three positions changed, the rest remains
|C|B|A|Y|E|P|\0|\0| //
^ ^ ^ updated values
当array_numbers_final
的新值发生错误:
|G|H|O|\0|\0|\0|\0|\0|
试图连接到name_cpu
,导致:
|C|B|A|Y|E|P|G|H|O| //attempt to write to memory not owned
^end of buffer
导致缓冲区溢出错误,并可能出现分段错误错误情况。 同样,和以前一样,设计变量以满足程序的潜在需求。 在这种情况下,以下将起作用:
char name_cpu[100] = {0};
char array_numbers_final[100] = {0};
回复原帖:
问题在这里:
strcat(name_cpu, array_numbers_final);//undefined behavior.
首先, name_cpu[8]
在声明时是未初始化的,也不是在使用前的任何时候初始化的。 因为不能保证内容是什么,所以不一定是字符串。 在任何字符串中使用此变量 function 可以调用未定义的行为
此外,(即使name_cpu
是有效字符串)当array_numbers_final
连接到name_cpu
时,缓冲区将溢出。 在我的测试运行中,我看到了这个:
解决方法是从用于预期目的的足够大小的初始化缓冲区开始。 例如:
char name_cpu[100] = {0}
array_numbers_final[100] = {0},
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
下面的代码示例是使用您提供的示例进行改编,并带有建议的编辑。 阅读在线评论:
int main(void)
{
int number_cpu = 3;//added - previously not defined in OP
int i = 0,
j = 0;
char name_cpu[100] = {0},//resized and initialize
array_numbers_final[100] = {0},//resized and initialize
array_letters[27] = "ABCDEFGHIJKLMNOPQRSTUWXYVZ",
array_numbers[10] = "123456789";
/* Generator data */
for(i = 0; i < number_cpu; i++)
{
for(j = 0; j < 3; j++){
name_cpu[j] = array_letters[rand() % (sizeof(array_letters)-1)];
array_numbers_final[j] = array_numbers[rand() % (sizeof(array_numbers)-1)];
}
strcat(name_cpu, array_numbers_final);
fprintf(stdout, "%s \n", name_cpu);//to stdout
// ^ changed here
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.