如何解决带有char []的C指针,忽略了const关键字?
我在C语言中做了一个小功能,它复制了char
数组。我不希望更改source
,所以我将const
放在函数声明和主体中,但是 它已更改。
main.c
#include "copy_char.h"
#include <stdio.h>
int main(void)
{
char source[] = { 'h','e','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
#include "copy_char.h"
void copy_char(const char* source,char* dest)
{
while(*source != 0)
{
*dest++ = *source++;
}
*dest = 0;
}
copy_char.h
#ifndef COPYCHAR_H
#define COPYCHAR_H
void copy_char(const char* source,char* dest);
#endif /* COPYCHAR_H */
谁能向我解释,为什么我的source
字符数组从hello
变为o
?
解决方法
缓冲区溢出。字符串source
比为dest
分配的内存长,因此,当您将source
复制到dest
时,您将遍历原本不希望的内存。然后发生奇怪的事情(未定义的行为)。
通过声明dest
的大小足以容纳“ hello”,可以使其足够大:
char dest[6] = { 'a','b','c',0 };
,
我不想更改源,因此我将const放入函数声明和主体中。但是,它改变了
const
限定符不能神奇地保护您避免在不应该编写的地方书写。仅仅是您与编译器之间的约定,上面写着“相信我,我不会修改此指针指向的内存”。
在函数中,您正在写入dest
末尾的数据,这是未定义的行为。您应该:
-
将最大长度传递给函数:
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; }
-
在
*source == 0
或*dest == 0
处停止:void copy_char(const char* source,char* dest) { while(*source != 0 && *dest != 0) { *dest++ = *source++; } *dest = 0; }
-
创建足够大的
dest
数组,并使函数保持不变。
函数的语义会根据您选择的选项而变化,哪个选项最适合您。
您的情况最有可能发生的情况是,source
正好在dest
的末尾,因此您用{{1覆盖了dest
的内容}},然后是'h','e','l','l'
的第一个字符和source
,然后是第二个字符的'o'
。幸运的是,您的程序不会崩溃,并且您在'\0'
中得到了一个有效字符串,即source
。尽管如此,无论您的程序看起来是否神奇地起作用,您都应该不要依赖未定义的行为。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。