Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我不知道';不理解内存分配和strcpy_C++_C_Arduino_Esp32 - Fatal编程技术网

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正确!该变量将流入地址空间,该地址空间是无保留的,或者是为其他变量保留的。因此,您要么修改其他变量,要么写入未使用的空间(到目前为止)。