附加两个字符时出现分段错误 - C++
我正在尝试附加两个字符,但由于某种原因我遇到了分段错误。
我的代码是这样的;
#include <string.h>
char *one = (char*)("one");
char *two = (char*)("two");
strcat(one, two);
我似乎在 strcat(one, Two)
处遇到分段错误,这是为什么?
I am trying to append two chars but for some reason I am getting a segmentation fault.
My code is like;
#include <string.h>
char *one = (char*)("one");
char *two = (char*)("two");
strcat(one, two);
and I seem to be getting a segmentation fault at strcat(one, two)
, why is that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
http://www.cplusplus.com/reference/clibrary/cstring/strcat/
strcat 的第一个参数必须足够大以容纳生成的字符串
尝试:
http://www.cplusplus.com/reference/clibrary/cstring/strcat/
the first parameter to strcat, must be big enough to hold the resulting string
try:
应该有足够的合法内存来保存整个字符串。
顺便说一句,如果你更喜欢在 C++ 中使用
std::string
而不是char*
,这样的事情会更容易处理:输出:
There should be enough legal memory to hold the entire string.
By the way, if you prefer using
std::string
overchar*
in C++, such thing would be easier to handle:Output:
这有两个原因。
如果您有一个初始化为字符串文字的指针,则该内存是只读的,修改它将导致未定义的行为。在这种情况下,如果您尝试将字符串附加到字符串文字,您将修改此类内存,这将导致问题。
使用 strcat 时,您需要保证指定位置处存在用于连接字符串的空间。在这种情况下,您不能保证这一点,因为只能保证字符串文字有足够的空间来保存文字本身。
要解决此问题,您需要显式分配一个足够大的缓冲区来容纳两个字符串的串联,包括空终止符。这是一种方法:
希望这有帮助!
There are two reasons for this.
If you have a pointer initialized to a string literal, that memory is read-only and modifying it will result in undefined behavior. In this case, if you try to append a string to a string literal, you'll be modifying this sort of memory, which will result in problems.
When using strcat you need to guarantee that space exists for the concatenation of the string at the location you're specifying. In this case, you cannot guarantee that, since a string literal is only guaranteed to have enough space to hold the literal itself.
To fix this, you'll want to explicitly allocate a buffer large enough to hold the concatenation of the two strings, including the null terminator. Here's one approach:
Hope this helps!
段错误是因为您尝试写入只读内存。 strcat 的第一个操作是将“t”从“two”的第一个条目复制到“one”末尾的 null 中。因此,严格来说,段错误并不是由于缺乏存储而导致的——我们从来没有走到这一步。事实上,这段代码也可能会给你一个段错误:
所有这些尝试做的就是将一个空值复制到一个空值上,但在只读内存中。我想优化器可能会在某些平台上阻止这种情况。
奇怪的是,下面的(不正确的)代码(可能)不会给你一个段错误,甚至给出“正确”的答案:
这成功地将“onetwo”写入我的机器上的标准输出。我们得到了一堆乱码,我们碰巧侥幸逃脱了。
另一方面,这会导致段错误:
因此解决方案:
当然,问题在于,要留出足够的空间来存储即将到来的内容有多大?
因此函数 strncat 或 strcat_s 或更简单的 std::string 。
这个故事的寓意是:在 C++ 中,就像 C 一样,您确实需要知道您的内存布局是什么。
The seg fault is because you attempt to write to read only memory. The first action of the strcat is to copy of 't' from the first entry of two into the null at the end of "one". So strictly the seg fault is not due to lack of storage - we never get that far. In fact this code will also likely give you a seg fault:
All this tries to do is copy a null over a null, but in read-only memory. I suppose a optimiser might happen to stop this on some platforms.
Oddly enough the following (incorrect) code will (probably) not give you a seg fault, and even give the "right" answer:
This successfully writes "onetwo" to stdout on my machine. We get a stack scribble, which we happen to get away with.
On the other hand this does seg fault:
Hence the solution:
The issue with this is of course, how large to make enoughSpace in order to store what ever is coming?
Hence the functions strncat, or strcat_s, or more easily std::string.
Moral of the story: in C++, just like C, you really need to know what your memory layout is.
这里有几个问题。首先,尽管您已将字符串转换为可变版本,但它们实际上是字符串文字,因此不应写入。其次,您使用 strcat 它将完全写入字符串缓冲区忽略字符串缓冲区的长度(最好使用 strncat ,它需要您指定缓冲区的长度)。最后,由于这是 C++,所以使用以下方法会更好:
There are several problems here. Firstly, though you have casted the strings to mutable versions, they really are string literals and hence should not be written. Secondly, you are using strcat which will write into the string buffer, completely ignoring the length of the string buffer (it's better to use strncat which requires you to specify the length of the buffer). Lastly, since this is C++, it would be way better to use:
你从来没有为你的字符串保留一些空间。
将是执行此操作的一种正确方法。另一种(也是更好的方法)是使用 std::string 类。
You never reserved some space for your strings.
Would be one correct way to do this. The other (and way better) is to use the
std::string
class.您的目标字符串应该足够大以容纳目标字符串和源字符串。所以一个例子是
<代码>
<代码>
Your destination string should be large enough to hold both the destination and the source string. So an example would be
strcat
需要一个“可写”缓冲区作为目标。在您的示例中,它是指向字符串常量(或文字)的指针,您无法写入该常量,因此会导致异常。目标缓冲区可以是堆栈上的缓冲区或动态分配的缓冲区(例如,使用 malloc)。strcat
needs a "writeable" buffer as the target. In your example, it is a pointer to a string constant (or literal), which you cannot write to, thus it results in an exception. The target buffer can be a buffer on the stack or one dynamically allocated (e.g., with malloc).这不是“空间不够”的问题。
看上面的代码,指针a指向“静态内存”。字符串“str”存储在PCB中的静态位置,这意味着它不能被覆盖。
所以,下面的代码会更好:
This is not the problem of "not enough space".
Look at the code above, the pointer a is point to "static memory". The string "str" is stored in the static place in the PCB, which means it can't be overwritten.
So, the codes below will be better: