来自GCC编译器的程序段错误:连接两个字符串

时间:2014-04-10 13:17:33

标签: c string pointers gcc

以下代码从 GCC 编译器中引发segment error

char *str1 = "India";
char *str2 = "BIX";
char *str3;
str3 = strcat(str1, str2);
printf("%s %s\n", str3, str1);

问题是str3=strcat(str1, str2)

所以我的问题是:对于GCC Compiler,它禁止两个指向同一个东西的指针?

5 个答案:

答案 0 :(得分:1)

通常,字符串文字将被放入只读内存区域,您对strcat()的调用将尝试写入此只读内存区域,因此会出现段错误。

答案 1 :(得分:1)

<强> strcat的

char * strcat ( char * destination, const char * source );

连接字符串 将源字符串的副本附加到目标字符串。目标中的终止空字符被源的第一个字符覆盖,并且在由目标中的两个串联形成的新字符串的末尾包含空字符。

目标 指向目标数组的指针,该数组应包含C字符串,并且足够大以包含连接的结果字符串。

但是你的目标不是指向一个数组的指针(它足够大以包含连接的结果字符串)它是指向sting文字的指针, 分段错误的原因是您要在只读存储器位置写入

答案 2 :(得分:1)

你应该用代码编写的内容回答你的问题:

char *str1 = "India";
char *str2 = "BIX";
//should have been
const char *str1 = "India";
const char *str2 = "BIX";

变量str1str2被分配了内存中字符串CONSTANTS IndiaBIX所在的地址。此内存只读。您正尝试使用strcat连接这两个字符串。好的,看看它的作用:

strcat(str1, str2);
       /\   take this
       || copy  ||
       ===========
        add to end

这需要str1指向一个足够大的内存块,以容纳它本身和你连接的字符。在字符串文字的情况下,情况绝对不是这样 还记得我是如何使用const存储类说明符编写代码的吗?现在看看strcat的原型:

char * strcat(char * destination, const char *source);

该函数期望第一个参数是常规char *,而不是const。这告诉您函数将尝试更改指针指向的内存。正如其他人所指出的,我在上面提到过:str1指针所指向的内存是只读,因此是段错误。

你能写的是:

char str1[15] = "India";
const char *str2 = "BIX";
strcat(str1, str2);

那应该有用。请注意strcat不检查/防止溢出。目标内存的大小应足够大,以容纳strlen(source) + strlen(destination) + 1。相反,使用strncat会更好!它允许您指定要连接到目标字符串的最大字符数:

size_t free_space = 15;
char str1[free_space] = "India";
const char *str2 = "BIX";
free_space -= strlen(str1) + 1;//add 1 here, to ensure we'll have room for the terminating \0 char
char *str3 = strncat(
    str1,
    str2,
    free_space
);
//now we've concatenated something onto our string, keep track of free space left:
free_space -= strlen(str2);//dangerous, though -> size_t is unsigned, perhaps best do:

size_t src_len = strlen(str2);
char *str3 = strncat(
    str1,
    str2,
    free_space
);
if (src_len >= free_space)
    free_space = 0;
else
    free_space -= src_len;

答案 3 :(得分:1)

尝试更改字符串文字会调用未定义的行为。它是只读的,即使它不是const合格的。

str3 = strcat(str1, str2);

上述语句调用具有原型

strcat
char *strcat(char *dest, const char *src);

这里dest是一个指向缓冲区的指针,该缓冲区足够大,可以将src指向的字符串附加到它上面。 str1是指向字符串文字的指针。因此,strcat将读取字符串str2的字符,并将其写入字符串str1之外,这是非法的。 您不需要将strcat的返回值保存在单独的char *变量中,因为它会修改其第一个参数。因此,在strcat返回后,src指向的字符串将附加到dest指向的字符串。您应该将代码更改为

#define MAX_SIZE 40

char str1[MAX_SIZE] = "India";
const char *str2 = "BIX";

// str1 must be large enough for 
// str2 to be appended to it
strcat(str1, str2);
printf("%s %s\n", str2, str1);

答案 4 :(得分:0)

你需要这个:

char str1[100] = "India";    // str1 is an array for maximum 100 chars, initialized with "India"
char *str2 = "BIX";          // str2 is a pointer to the string literal "BIX" (read only)
char *str3 ;                 // str3 is pointer to char

str3 = strcat(str1, str2);   // appends "BIX" to "India" in the str1 buffer and puts str1 in str3
printf("%s %s\n", str3, str1);