[英]C pointer with char[], const keyword ignored?
I made a little function in C which copies a char
array.我在 C 中做了一个小函数,它复制了一个
char
数组。 I didn't want source
to be changed, so I put const
into the function declaration and body, but it changed.我不想更改
source
,所以我将const
放入函数声明和主体中,但它更改了。
main.c主文件
#include "copy_char.h"
#include <stdio.h>
int main(void)
{
char source[] = { 'h', 'e', 'l', 'l', 'o', 0 };
char dest[] = { 'a', 'b', 'c', 0 };
printf("%s\n", source); // hello
printf("%s\n", dest); // abc
copy_char(source, dest);
printf("%s\n", source); // o (?) - why did this change?
printf("%s\n", dest); // hello
}
copy_char.c复制字符.c
#include "copy_char.h"
void copy_char(const char* source, char* dest)
{
while(*source != 0)
{
*dest++ = *source++;
}
*dest = 0;
}
copy_char.h复制字符.h
#ifndef COPYCHAR_H
#define COPYCHAR_H
void copy_char(const char* source, char* dest);
#endif /* COPYCHAR_H */
Can anyone explain to me, why did my source
char array change from hello
to o
?谁能向我解释一下,为什么我的
source
字符数组从hello
变为o
?
Buffer overrun.缓冲区溢出。 The string
source
is longer than the memory allocated for dest
, so when you copy source
to dest
you are tromping over memory you didn't intend to.字符串
source
比为dest
分配的内存长,因此当您将source
复制到dest
您正在遍历您不想要的内存。 Weird things then happen (undefined behavior).然后会发生奇怪的事情(未定义的行为)。
You can make dest
big enough by declaring its size to be big enough for "hello":您可以通过将
dest
的大小声明为足以容纳“hello”来使dest
足够大:
char dest[6] = { 'a', 'b', 'c', 0 };
I didn't want source to be changed, so I put const into function declaration and body.
我不想更改源代码,因此我将 const 放入函数声明和主体中。 but, it changed
但是,它变了
The const
qualifier does not magically protect you from writing where you should not. const
限定符并不能神奇地保护您不写不该写的地方。 It's merely a contract between you and the compiler that says "trust me, I am not going to modify the memory pointed to by this pointer".这只是你和编译器之间的契约,上面写着“相信我,我不会修改这个指针指向的内存”。
In your function you are writing data past the end of dest
, which is undefined behavior.在您的函数中,您正在写入超过
dest
末尾的数据,这是未定义的行为。 You should either:你应该:
Pass a maximum length to the function:将最大长度传递给函数:
void copy_char(const char* source, char* dest, size_t maxlen) { size_t i; for (i = 0; i < maxlen && source[i]; i++) { dest[i] = source[i]; } dest[i] = 0; }
Stop at either *source == 0
or *dest == 0
:在
*source == 0
或*dest == 0
处停止:
void copy_char(const char* source, char* dest) { while(*source != 0 && *dest != 0) { *dest++ = *source++; } *dest = 0; }
Create a big enough dest
array and leave the function unchanged.创建一个足够大的
dest
数组并保持函数不变。
The semantics of the function change depending on which option you choose, which one is the right one is up to you.函数的语义会根据您选择的选项而变化,哪个是正确的取决于您。
What most likely is happening in your case is that it just so happens that source
is right past the end of dest
, so you overwrite the contents of dest
with 'h','e','l','l'
, then the first character of source
with 'o'
and then the second one with '\\0'
.在您的情况下最有可能发生的情况是
source
恰好在dest
的末尾之后,因此您用'h','e','l','l'
覆盖了dest
的内容,然后source
第一个字符为'o'
,第二个字符为'\\0'
。 Luckily enough, your program does not crash, and you end up with a valid string in source
that is "o"
.幸运的是,您的程序没有崩溃,最终在
source
中得到一个有效的字符串"o"
。 Nonetheless, you should never rely on undefined behavior , whether your program seems to magically work or not.尽管如此,你永远不应该依赖未定义的行为,无论你的程序是否神奇地工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.