为什么我的 char* 在 C++ 中可写,有时只读

发布于 2024-08-20 15:21:39 字数 866 浏览 5 评论 0原文

我最近在理解 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

意犹 2024-08-27 15:21:39

关键是其中一些指针指向分配的内存(可读/写),其中一些指针指向字符串常量。字符串常量存储在与分配的内存不同的位置,并且不能更改。嗯,大多数时候。系统中的漏洞通常是代码或常量被更改的结果,但这是另一回事了。

无论如何,关键是使用 new 关键字,这是在读/写内存中分配空间,因此您可以更改该内存。

这个语句是错误的,

char * bob = new char[6];
bob = "hello\0";

因为您正在更改指针而不是复制数据。你想要的是这样的:

char * bob = new char[6];
strcpy(bob,"hello");

或者

strncpy(bob,"hello",6);

你不需要这里的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

char * bob = new char[6];
bob = "hello\0";

because you are changing the pointer not copying the data. What you want is this:

char * bob = new char[6];
strcpy(bob,"hello");

or

strncpy(bob,"hello",6);

You don't need the nul here because a string constant "hello" will have the null placed by the compiler.

遗弃M 2024-08-27 15:21:39
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");
char * bob = "hello"; 

This actually translated to:

const char __hello[] = "hello";
char * bob = (char*) __hello;

You can't change it, because if you'd written:

char * bob = "hello"; 
char * sam = "hello"; 

It could be translated to:

const char __hello[] = "hello";
char * bob = (char*) __hello;
char * sam = (char*) __hello;

now, when you write:

char * bob = new char[6];    
bob = "hello\0";

First you assign one value to bob, then you assign a new value to it. What you really want to do here is:

char * bob = new char[6];    
strcpy(bob, "hello");
橘寄 2024-08-27 15:21:39

您应该始终使用 char const* 作为指向字符串文字(双引号中的内容)的指针。尽管该标准也允许 char*,但它不允许写入字符串文字。 GCC 会在将文字地址分配给 char* 时发出编译警告,但显然其他一些编译器不会这样做。

You should always use char const* for pointers to string literals (stuff in double quotes). Even though the standard allows char* as well, it does not allow writing to the string literal. GCC gives a compile warning for assigning a literal address into char*, but apparently some other compilers don't.

七禾 2024-08-27 15:21:39

编辑:问题被重新标记为 C++,而不是最初存在但被重新标记的 C...

好的。你把一些事情搞混了......
new 由 C++ 使用,而不是 C。

  • 情况#1。这就是声明一个指向 char 的指针。您应该能够操作该字符串...您可以显示交换字符的代码吗?
  • 案例#2/#3。你得到了随机的废话,并发现一个 nul 终止符,即 '\0'...占据了你在 C/C++ 期间遇到的每一个字符串,可能在你的余生中...
+-+-+-+-+-+--+
|H|e|l|l|o|\0|
+-+-+-+-+-+--+
            ^
            |
         Nul Terminator
  • 情况#4 确实不起作用,因为您需要使用 strcpy 来完成这项工作,当您声明字符串 char * 时,您不能在调用 new 后简单地分配这样的字符串s = "foo"; 在编译时初始化。但是当你这样做时, char *s = new char[6]; strcpy(s, "hello"); 被复制到指针变量 s 中。

您最终会发现,指向 s 占用的内存块的指针很容易被覆盖,当您意识到必须小心防止缓冲区溢出时,这会引起一阵混乱......请记住与 nul 终止符相关的案例#3...不要忘记,实际上,该字符串的长度是 6,而不是 5,因为我们考虑了 nul 终止符。

  • 案例#5。这是声明一个指向 char 类型数组的指针,即一个多维数组,这样想
*(bob + 0) = "foo";
*(bob + 1) = "bar";

我知道有很多东西需要消化...但请随意发布任何进一步的想法...:) 最好的学习上的运气...

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.

  • Case #1. That is declaring a pointer to char. You should be able to manipulate the string...can you show the code in what you did to do swapping characters.
  • Case #2/#3. That you got random crap, and discovered that a nul terminator i.e. '\0'...occupies every single string you'll encounter for the duration of C/C++, possibly for the rest of your life...
+-+-+-+-+-+--+
|H|e|l|l|o|\0|
+-+-+-+-+-+--+
            ^
            |
         Nul Terminator
  • Case #4 did not work as you need to use a strcpy to do that job, you cannot simply assign a string like that after calling new, when you declare a string char *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 variable s.

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.

  • Case #5. That is declaring a pointer to array of type char, i.e. a multi-dimensional array, think of it like this
*(bob + 0) = "foo";
*(bob + 1) = "bar";

I know there is a lot to digest...but feel free to post any further thoughts... :) And best of luck in learning...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文