C++ 我不知道';不理解内存分配和strcpy
以下是我的代码示例:C++ 我不知道';不理解内存分配和strcpy,c++,c,arduino,esp32,C++,C,Arduino,Esp32,以下是我的代码示例: char chipid[13]; void initChipID(){ write_to_logs("Called initChipID"); strcpy(chipid, string2char(twelve_char_string)); write_to_logs("Chip ID: " + String(chipid)); } 我不明白的是:即使我将chipid定义为char[2],我仍然会将预期结果打印到日志中 为什么呢?为chipid分配的内存空间
char chipid[13];
void initChipID(){
write_to_logs("Called initChipID");
strcpy(chipid, string2char(twelve_char_string));
write_to_logs("Chip ID: " + String(chipid));
}
我不明白的是:即使我将chipid定义为char[2],我仍然会将预期结果打印到日志中
为什么呢?为chipid分配的内存空间不应该被strcpy溢出,并且只打印字符串的前2个字符吗?您的部分是正确的:“为chipid分配的内存空间被strcpy溢出”——这是正确的。这就是为什么会得到完整的结果(溢出的结果是未定义的,可能是崩溃或其他结果)。C/C++在内存方面为您提供了强大的功能。强大的力量带来巨大的责任。你所做的会产生未定义的行为,这意味着它可能会起作用。但是,当strcpy写入不应该写入的内存时,它肯定会在以后出现问题 您会发现,在C/C++中,许多事情都可以解决。然而,当你的程序意外崩溃时,类似的事情会让你头疼,这可能是在你的程序的一个完全不同的部分,这使得调试变得困难
无论如何,如果你使用C++,你应该使用STD::String,这使得事情变得容易很多。 我不明白的是:即使我将chipid定义为char[2],我也会 仍然可以将预期结果打印到日志中
那你就(不)幸运了。如果溢出产生的未定义行为没有表现为其他数据的损坏,但也没有使程序崩溃,那么您就特别幸运了。这种行为是未定义的,所以你不应该把它的任何表现解释为你应该依赖的东西,或者是语言所指定的东西 为什么呢 语言没有指定它将发生,当然也没有指定在您的案例中发生的原因 实际上,您观察到的清单显示就好像strcpy将完整数据写入内存中的位置,该位置从数组的开头开始,一直延伸到数组的结尾,覆盖程序可能存储在该空间中的任何其他内容,程序随后通过相应的溢出读取将其读回 为芯片ID分配的内存空间不应该是 被strcpy溢出 对 并且只有字符串的前2个字符是 印刷品不,该语言不指定一旦程序通过执行缓冲区溢出(或通过其他方式)来执行UB时会发生什么。但也不是,C数组在内存中仅表示为连续元素的平面序列,没有显式边界。这就是C字符串需要终止的原因。字符串函数看不到包含字符串元素的数组的声明大小,它们只看到元素序列。
strcpy是否应该溢出为芯片ID分配的内存空间
是并且只打印字符串的前2个字符?
否。这是未定义的行为。欢迎来到未定义的行为领域,在那里一切都是可能的。我是否冒着内存被重新分配到另一个变量的风险,并且只剩下前2个字符被安全存储?是的,这是其中的一个风险。这就是为什么它是未定义的行为。@Eric正确!该变量将流入地址空间,该地址空间是无保留的,或者是为其他变量保留的。因此,您要么修改其他变量,要么写入未使用的空间(到目前为止)。