我试图附加两个字符但由于某种原因我遇到了分段错误。
我的代码就像;
#include <string.h>
char *one = (char*)("one");
char *two = (char*)("two");
strcat(one, two);
我似乎在strcat(one, two)
遇到了分段错误,为什么会这样?
答案 0 :(得分:5)
http://www.cplusplus.com/reference/clibrary/cstring/strcat/
strcat的第一个参数,必须足够大才能保存结果字符串
尝试:
//assuming a,b are char*
char* sum = new char[strlen(a) +strlen(b)+1];
strcpy(sum,a);
strcat(sum,b);
答案 1 :(得分:3)
应该有足够的合法内存来保存整个字符串。
char *one = new char[128]; //allocating enough memory!
const char *two = "two"; //"two" is const char*
strcpy(one, "one");
strcat(one, two); //now the variable "one" has enough memory to hold the entire string
顺便说一句,如果您更喜欢在C ++中使用std::string
而不是char*
,那么这样的事情会更容易处理:
#include<string>
std::string one = "one";
std::string two = "two";
one = one + two; //Concatenate
std::cout << one;
输出:
onetwo
答案 2 :(得分:2)
这有两个原因。
如果您将指针初始化为字符串文字,则该内存是只读的,修改它将导致未定义的行为。在这种情况下,如果您尝试将字符串附加到字符串文字,您将修改此类内存,这将导致问题。
使用strcat时,您需要保证在您指定的位置连接字符串的空间。在这种情况下,您无法保证,因为字符串文字只能保证有足够的空间来容纳文字本身。
要解决此问题,您需要显式分配足够大的缓冲区来保存两个字符串的串联,包括空终止符。这是一种方法:
char* buffer = malloc(strlen(one) + strlen(two) + 1);
strcpy(buffer, one);
strcat(buffer, two);
希望这有帮助!
答案 3 :(得分:2)
seg错误是因为您尝试写入只读内存。 strcat的第一个动作是将't'从第一个条目2复制到“one”结尾处的null。严格来说,seg故障不是由于缺乏存储 - 我们从来没有这么做过。事实上,这段代码也可能会给你一个seg错误:
char* one = "one";
char* two = "";
strcat(one, two);
所有这些尝试都是在null上复制null,但是在只读内存中。我想一个优化器可能会在某些平台上阻止它。
奇怪的是,以下(不正确的)代码(可能)不会给你一个段错误,甚至给出“正确”的答案:
char one[] = "one";
char two[] = "two";
strcat(one, two);
printf("%s\n", one);
这成功地将“onetwo”写入我的机器上的stdout。我们得到了一个堆栈涂鸦,我们碰巧可以逃脱。
另一方面,这确实是一个错误:
char* one = "one "; // Plenty of storage, but not writable.
char two[] = "two";
strcat(one,two);
因此解决方案:
const unsigned enoughSpace = 32;
char one[enoughSpace] = "one";
char two[] = "two";
strcat(one,two);
printf("%s\n", one);
这个问题当然是为了存储将要发生的事情而制作足够多的空间?
因此函数strncat或strcat_s,或者更容易std :: string。
故事的道德:在C ++中,就像C一样,你真的需要知道你的内存布局是什么。
答案 4 :(得分:1)
你永远不会为你的琴弦预留一些空间。
#include <string.h>
#include <stdio.h>
int main(void){
char str[20] = "";
strcat(str, "one");
strcat(str, "two");
printf("%s", str);
}
这是一种正确的方法。另一种(更好的方法)是使用std::string
类。
#include <string>
#include <cstdio>
int main(void){
std::string str;
str += "one";
str += "two";
std::printf("%s", str.c_str());
}
答案 5 :(得分:1)
这里有几个问题。首先,虽然你已经将字符串转换为可变版本,但它们确实是字符串文字,因此不应该编写。其次,您使用strcat将写入字符串缓冲区,完全忽略字符串缓冲区的长度(最好使用strncat,这需要您指定缓冲区的长度)。最后,因为这是C ++,所以使用它会更好:
#include <string>
// ...
string one = "one";
string two = "two";
one.append(two);
答案 6 :(得分:0)
strcat
需要一个“可写”缓冲区作为目标。在您的示例中,它是指向字符串常量(或文字)的指针,您无法写入,因此会导致异常。目标缓冲区可以是堆栈上的缓冲区,也可以是动态分配的缓冲区(例如,使用malloc)。
答案 7 :(得分:0)
您的目标字符串应足够大,以容纳目标字符串和源字符串。所以一个例子就是
char one[10] = "one";
char two[4] = "two";
strcat(one,two);
char one[10] = "one";
char two[4] = "two";
strcat(one,two);
答案 8 :(得分:0)
这不是“空间不足”的问题。
char *a = "str";
查看上面的代码,指针a指向“静态内存”。字符串“str”存储在PCB中的静态位置,这意味着它不能被覆盖。
所以,下面的代码会更好:
#include <string>
using std::string;
string a = "stra";
string b = "strb";
a += b;