我最近有一些很大的问题了解char*
。
假设我做了一个递归函数来恢复char*
但是根据我如何初始化它我得到了一些访问冲突,在我的C ++入门中我没有找到任何给我正确的理解路径所以我正在寻求你的帮助。
案例1 在尝试交换字母时我遇到访问冲突的第一种情况:
char * bob = "hello";
案例2 然后我尝试了这项工作
char * bob = new char[5];
bob[0] = 'h';
bob[1] = 'e';
bob[2] = 'l';
bob[3] = 'l';
bob[4] = 'o';
CASE 3 但是当我做了一个cout时,我最后得到了一些随机的废话,所以我改了它
char * bob = new char[6];
bob[0] = 'h';
bob[1] = 'e';
bob[2] = 'l';
bob[3] = 'l';
bob[4] = 'o';
bob[5] = '\0';
案例4 这样做有效,所以我告诉自己为什么不能这样做呢
char * bob = new char[6];
bob = "hello\0";
CASE 5 ,它失败了,我也读到某个地方,你可以做点什么
char* bob[];
然后添加一些内容。 我的问题是为什么有些失败而其他失败,以及最好的方法是什么?
答案 0 :(得分:11)
关键是这些指针中的一些指向分配的内存(读/写),其中一些指针指向字符串常量。字符串常量存储在与分配的内存不同的位置,并且不能更改。好吧大部分时间。系统中的漏洞通常是代码或常量被更改的结果,但这是另一个故事。
在任何情况下,关键是使用new关键字,这是在读/写内存中分配空间,因此您可以更改该内存。
这句话错了
char * bob = new char[6];
bob = "hello\0";
因为您正在更改指针而不是复制数据。你想要的是这个:
char * bob = new char[6];
strcpy(bob,"hello");
或
strncpy(bob,"hello",6);
这里不需要nul,因为字符串常量"hello"
将使编译器放置空值。
答案 1 :(得分:1)
char * bob = "hello";
这实际上翻译为:
const char __hello[] = "hello";
char * bob = (char*) __hello;
你不能改变它,因为如果你写了:
char * bob = "hello";
char * sam = "hello";
可以翻译为:
const char __hello[] = "hello";
char * bob = (char*) __hello;
char * sam = (char*) __hello;
现在,当你写:
char * bob = new char[6];
bob = "hello\0";
首先为bob分配一个值,然后为其分配一个新值。你真正想做的是:
char * bob = new char[6];
strcpy(bob, "hello");
答案 2 :(得分:1)
编辑:这个问题被重新命名为C ++,而不是C,最初是C,但重新标记....
<击>确定。你有几件事搞砸了......
new
由C ++使用,而不是C.
+-+-+-+-+-+--+ |H|e|l|l|o|\0| +-+-+-+-+-+--+ ^ | Nul Terminator
strcpy
来完成这项工作,当你声明一个字符串{{1}时,你不能简单地在调用new
后分配这样的字符串在编译时初始化的。但是当你这样做时,char *s = "foo";
会被复制到指针变量char *s = new char[6]; strcpy(s, "hello");
中。 你最终会发现这个指向s
占用的内存块的指针很容易被覆盖,当你意识到必须小心防止缓冲区溢出时,这会引起一系列的错误。记住与nul终结符相关的案例#3 ...不要忘记,确实,该字符串的长度为6,而不是5,因为我们考虑了nul终止符。
*(bob + 0) = "foo"; *(bob + 1) = "bar";
我知道有很多东西要消化......但随意发表任何进一步的想法...... :)祝你学习好运......
答案 3 :(得分:1)
你应该总是使用char const*
来指示字符串文字(双引号中的东西)。即使标准允许char*
,它也不允许写入字符串文字。 GCC给出了一个编译警告,用于将文字地址分配到char*
,但显然其他一些编译器没有。{/ p>