2

使用 strcpy 后源被损坏并获得正确的目的地。以下是我的代码,请告诉我为什么我的源代码被破坏了?如果我对第二个字符数组 q[] 保持固定大小,那么我的源不会被更改。为什么会出现这种奇怪的行为。-
我正在使用 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);
}

输出:

after function calling...
string1:        ld
string2:        Hello world

在此先感谢,
马拉地语

4

7 回答 7

8

strcpy不分配存储字符串所需的内存。在str2执行strcpy. 否则,当您覆盖一些未分配的内存时,您会得到未定义的行为。

于 2011-03-17T13:39:49.170 回答
6

q只有 1 个字符的空间,即终止\0。请阅读一本关于 C 的书——你需要学习一些关于内存管理的知识。

很可能你的记忆看起来像这样(简化)Qpppppppppppp:. 所以当你 strcpy to 时q,你会覆盖p's 的部分内存。

由于您使用的是 C++:只需使用std::string和或std::stringstream代替原始字符数组。

于 2011-03-17T13:39:32.160 回答
4

在您的代码中,q, 是一个单元素数组(基于 的长度"",由于空终止符而等于 1),因此它不能包含整个字符串。因此,您不能执行 a strcpy,因为它会覆盖无效的内存位置(尝试将太多数据写入数组)。

声明q足够大以包含您的字符串。此外,您可以使用strncpy以确保安全。

于 2011-03-17T13:40:51.473 回答
3

char q[] = "";创建一个只有 1 个元素的字符数组 - 将更多数据复制到其中不会为其保留更多内存。

所以,当你写过去为 q 保留的空间时,你会开始覆盖 p 中的内容——这两个变量在内存中彼此相邻。

于 2011-03-17T13:39:36.673 回答
3

大家说的都对了一半。代码失败,因为没有为副本保留空间,正如其他人正确指出的那样。缺少的部分是您的对象在堆栈上,而不是堆上。因此,由于堆栈无法再展开,您的代码不仅可能而且不可避免地会损坏。

于 2011-03-17T14:43:21.353 回答
2

数组“q”只有一个字节长;它绝对没有空间容纳字符串“Hello, World”!当您尝试将“Hello, World”复制到 q 时,您最终会超出 q 的边界并覆盖堆栈上与其相邻的 p。我想象绘制这些东西在堆栈上的布局图,您可以确切地确定为什么最终在 p 中的垃圾只是“ld”。

于 2011-03-17T13:42:54.087 回答
2

strcpy 期望您提供分配的存储缓冲区,而不仅仅是 char* 指针。如果你改变char q[]="";char q[50];会工作。由于您只给 strcpy 一个指向零长度字符串的指针,因此它没有足够的空间来存储复制的字符串并覆盖也就是破坏内存。

于 2011-03-17T13:50:13.017 回答