C++ 为什么在c中使用strcpy时我的源代码发生了变化
使用strcpy后,源已损坏,并且目标已正确。下面是我的代码,请告诉我为什么我的源代码被破坏了?如果我保持第二个字符数组q[]的固定大小,则不会更改源。为什么会有这种奇怪的行为-C++ 为什么在c中使用strcpy时我的源代码发生了变化,c++,c,strcpy,C++,C,Strcpy,使用strcpy后,源已损坏,并且目标已正确。下面是我的代码,请告诉我为什么我的源代码被破坏了?如果我保持第二个字符数组q[]的固定大小,则不会更改源。为什么会有这种奇怪的行为- 我正在使用MSVC 2005 void function(char* str1,char* str2); void main() { char p[]="Hello world"; char q[]=""; function(p,q); cout<<"after funct
我正在使用MSVC 2005
void function(char* str1,char* str2);
void main()
{
char p[]="Hello world";
char q[]="";
function(p,q);
cout<<"after function calling..."<<endl;
cout<<"string1:"<<"\t"<<p<<endl;
cout<<"string2:"<<"\t"<<q<<endl;
cin.get();
}
void function(char* str1, char* str2)
{
strcpy(str2,str1);
}
提前感谢,Malathi
q
只有一个字符的空格,该字符是终止的\0
。
请阅读一本关于C语言的书——你需要学习一些关于内存管理的知识
很可能您的内存是这样的(简化):qppppppppp
。因此,当您复制到q
时,您将覆盖p
的部分内存
由于您使用的是C++:只需使用std::string
和或std::stringstream
而不是原始字符数组代码>创建一个正好包含1个元素的字符数组-将更多数据复制到该数组中不会为其保留更多内存
因此,发生的情况是,当您写入超过为q保留的空间时,您开始覆盖p中的内容-这两个变量在内存中彼此相邻。
strcpy
不分配存储字符串所需的内存。
在执行strcpy操作之前,必须在str2中分配足够的内存。
否则,当您覆盖一些未分配的内存时,会出现未定义的行为。在您的代码中,
q
是一个单元素数组(基于“
的长度,由于使用空终止符,该长度等于一),因此它不能包含整个字符串。因此,您不能执行strcpy,因为它会写入无效的内存位置(试图向数组写入太多数据)
声明
q
足够大,可以容纳字符串。另外,为了安全起见,您可以使用strncpy;它绝对没有空间放“你好,世界”!当您尝试将“Hello,World”复制到q时,最终会超出q的边界并覆盖p,p在堆栈上与q相邻。我想象一下,画一张这些东西在堆栈上的布局图,您可以确切地确定为什么p中的垃圾只是“ld”。strcpy希望您提供一个分配的存储缓冲区,而不仅仅是一个char*指针。如果您更改char q[]=”代码>至字符q[50]代码>它会工作的。因为您只给strcpy一个指向零长度字符串的指针,所以它没有足够的空间来存储复制的字符串,并且覆盖aka会破坏内存。每个人说的话都有一半是正确的。代码失败是因为没有像其他人正确指出的那样为副本保留空间。缺少的部分是对象在堆栈上,而不是堆上。因此,您的代码不仅很可能会损坏,而且不可避免地会损坏,因为堆栈无法再解开。“使用strcpy源代码后,代码会损坏并获得正确的目标”,这是没有意义的。@Daniel,是的,这是有意义的,因为q上的strcpy会覆盖为p分配的内存。它会被损坏并获得正确的目标。对不起,我不明白那句话背后的意思。第二次看到strcpy(…)和chq[]=“”,我理解了实际问题。如果使用C++,使用STD::String可能是合理的。运算符=完全满足您的需要。@Daniel:这是源字符串,不是源代码。这让我有点困惑。遗憾的是,strncpy不是一个“安全的”strcpy
,而是用于固定大小的字符串,因此如果字符串与缓冲区一样长,它不会NUL终止它。非标准安全选项是strlcpy
。很抱歉,Ernest没有看到您的评论。
after function calling...
string1: ld
string2: Hello world