在不同的 char 数组上调用 strcpy 时,char 数组的值发生变化
Value of char array changing, upon calling strcpy on a different char array
在尝试将字符串复制到 C 样式数组的方法时,由于一些奇怪的限制,我偶然发现了这种奇怪的行为,首先尝试使用 std::string::copy()
复制字符串似乎工作正常,直到我尝试使用 std::strcpy()
将相同的字符串从另一个变量复制到另一个空的 C 样式数组中,然后第一个数组的内容从字符串中获取一些剩余内容。
#include <iostream>
#include <string>
#include <algorithm>
#include "string.h"
int main()
{
std::string str = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";
std::string str2 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";
char cstr[64] = {0};
char cstr2[64] = {0};
str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));
// cstr: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
std::cout << "cstr: \"" << cstr << "\"" << std::endl;
strcpy(cstr2, str2.c_str());
cstr2[sizeof(cstr2) / sizeof(cstr2[0]) - 1] = '[=10=]';
// cstr: "m nonumy eirmod tempor invidunt ut l"
std::cout << "cstr: \"" << cstr << "\"" << std::endl;
// cstr2: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
std::cout << "cstr2: \"" << cstr2 << "\"" << std::endl;
return 0;
}
当然,我只是在这里遗漏了一些愚蠢的关键点。
strcpy(cstr2, str2.c_str());
是 未定义的行为 ,因为它试图复制超过 64 个字节。
其余代码无关紧要。
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l
1234567890123456789012345678901234567890123456789012345678901234
第一种情况
str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));
您通过 sizeof( cstr ) - 1
的值限制了复制的字符数。
所以数组 cstr
包含一个字符串,因为它是零初始化的。
第二种情况你没有限制复制的字符数。
strcpy(cstr2, str2.c_str());
所以数组cstr2
之外的内存被覆盖了,因为str2.c_str()
指向的字符串包含的字符数超过了数组cstr2
的大小。
你可以这样写
strncpy( cstr2, str2.c_str(), sizeof( cstr2 ) - 1 );
使用函数 strncpy
.
在尝试将字符串复制到 C 样式数组的方法时,由于一些奇怪的限制,我偶然发现了这种奇怪的行为,首先尝试使用 std::string::copy()
复制字符串似乎工作正常,直到我尝试使用 std::strcpy()
将相同的字符串从另一个变量复制到另一个空的 C 样式数组中,然后第一个数组的内容从字符串中获取一些剩余内容。
#include <iostream>
#include <string>
#include <algorithm>
#include "string.h"
int main()
{
std::string str = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";
std::string str2 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";
char cstr[64] = {0};
char cstr2[64] = {0};
str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));
// cstr: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
std::cout << "cstr: \"" << cstr << "\"" << std::endl;
strcpy(cstr2, str2.c_str());
cstr2[sizeof(cstr2) / sizeof(cstr2[0]) - 1] = '[=10=]';
// cstr: "m nonumy eirmod tempor invidunt ut l"
std::cout << "cstr: \"" << cstr << "\"" << std::endl;
// cstr2: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
std::cout << "cstr2: \"" << cstr2 << "\"" << std::endl;
return 0;
}
当然,我只是在这里遗漏了一些愚蠢的关键点。
strcpy(cstr2, str2.c_str());
是 未定义的行为 ,因为它试图复制超过 64 个字节。
其余代码无关紧要。
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l
1234567890123456789012345678901234567890123456789012345678901234
第一种情况
str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));
您通过 sizeof( cstr ) - 1
的值限制了复制的字符数。
所以数组 cstr
包含一个字符串,因为它是零初始化的。
第二种情况你没有限制复制的字符数。
strcpy(cstr2, str2.c_str());
所以数组cstr2
之外的内存被覆盖了,因为str2.c_str()
指向的字符串包含的字符数超过了数组cstr2
的大小。
你可以这样写
strncpy( cstr2, str2.c_str(), sizeof( cstr2 ) - 1 );
使用函数 strncpy
.