为什么我的 char* 在 C++ 中可写,有时只读
我最近在理解 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';
案例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';
CASE 4,这有效,所以我告诉自己为什么这不起作用,然后
char * bob = new char[6];
bob = "hello\0";
CASE 5并且它失败了,我也在某处读过你可以做类似的事情
char* bob[];
然后添加一些东西。 我的问题是为什么有些会失败而另一些则不会,最好的方法是什么?
I have had really big problems understand the char*
lately.
Let's say I made a recursive function to revert a char*
but depending on how I initialize it I get some access violations, and in my C++ primer I didn't find anything giving me the right path to understand so I am seeking your help.
CASE 1
First case where I got access violation when trying to swap letters around:
char * bob = "hello";
CASE 2 Then I tried this to get it work
char * bob = new char[5];
bob[0] = 'h';
bob[1] = 'e';
bob[2] = 'l';
bob[3] = 'l';
bob[4] = 'o';
CASE 3 But then when I did a cout I got some random crap at the end so I changed it for
char * bob = new char[6];
bob[0] = 'h';
bob[1] = 'e';
bob[2] = 'l';
bob[3] = 'l';
bob[4] = 'o';
bob[5] = '\0';
CASE 4 That worked so I told myself why wouldn't this work then
char * bob = new char[6];
bob = "hello\0";
CASE 5 and it failed, I have also read somewhere that you could do something like
char* bob[];
Then add something to that.
My question is why do some fail and other not, and what is the best way to do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
关键是其中一些指针指向分配的内存(可读/写),其中一些指针指向字符串常量。字符串常量存储在与分配的内存不同的位置,并且不能更改。嗯,大多数时候。系统中的漏洞通常是代码或常量被更改的结果,但这是另一回事了。
无论如何,关键是使用 new 关键字,这是在读/写内存中分配空间,因此您可以更改该内存。
这个语句是错误的,
因为您正在更改指针而不是复制数据。你想要的是这样的:
或者
你不需要这里的nul,因为字符串常量
“hello”
将由编译器放置null。The key is that some of these pointers are pointing at allocated memory (which is read/write) and some of them are pointing at string constants. String constants are stored in a different location than the allocated memory, and can't be changed. Well most of the time. Often vulnerabilities in systems are the result of code or constants being changed, but that is another story.
In any case, the key is the use of the new keyword, this is allocating space in read/write memory and thus you can change that memory.
This statement is wrong
because you are changing the pointer not copying the data. What you want is this:
or
You don't need the nul here because a string constant
"hello"
will have the null placed by the compiler.这实际上翻译为:
你不能改变它,因为如果你写:
它可以翻译为:
现在,当你写:
首先你给 bob 分配一个值,然后你给它分配一个新值。你真正想做的是:
This actually translated to:
You can't change it, because if you'd written:
It could be translated to:
now, when you write:
First you assign one value to bob, then you assign a new value to it. What you really want to do here is:
您应该始终使用 char const* 作为指向字符串文字(双引号中的内容)的指针。尽管该标准也允许
char*
,但它不允许写入字符串文字。 GCC 会在将文字地址分配给 char* 时发出编译警告,但显然其他一些编译器不会这样做。You should always use
char const*
for pointers to string literals (stuff in double quotes). Even though the standard allowschar*
as well, it does not allow writing to the string literal. GCC gives a compile warning for assigning a literal address intochar*
, but apparently some other compilers don't.编辑:问题被重新标记为 C++,而不是最初存在但被重新标记的 C...
好的。你把一些事情搞混了......
new
由 C++ 使用,而不是 C。strcpy
来完成这项工作,当您声明字符串char * 时,您不能在调用
在编译时初始化。但是当你这样做时, char *s = new char[6]; strcpy(s, "hello"); 被复制到指针变量new
后简单地分配这样的字符串s = "foo";s
中。您最终会发现,指向
s
占用的内存块的指针很容易被覆盖,当您意识到必须小心防止缓冲区溢出时,这会引起一阵混乱......请记住与 nul 终止符相关的案例#3...不要忘记,实际上,该字符串的长度是 6,而不是 5,因为我们考虑了 nul 终止符。我知道有很多东西需要消化...但请随意发布任何进一步的想法...:) 最好的学习上的运气...
Edit: The question was retagged as C++ instead of C which was originally there but re-tagged....
Ok. You have got a couple of things mixed up...
new
is used by C++, not C.strcpy
to do that job, you cannot simply assign a string like that after callingnew
, when you declare a stringchar *s = "foo";
that is initialized at compile time. But when you do it this way,char *s = new char[6]; strcpy(s, "hello");
that gets copied into the pointer variables
.You will eventually discover that this pointer to a memory block occupied by
s
will easily get over-written which will induce a fit of conniptions as you realize that you have to be careful to prevent buffer overflows...Remember Case #3 in relation to nul terminator...don't forget that, really, that string's length is 6, not 5 as we're taking into account of the nul terminator.I know there is a lot to digest...but feel free to post any further thoughts... :) And best of luck in learning...