我不了解内存分配和strcpy

时间:2019-07-11 14:05:45

标签: c++ c arduino esp32

这是我的代码示例:

let a : String = "A" 
let b : String = "B" 
let c = letterDictionary["C"]

let imageName : String = a + b + c //error 
let imageName : String = a + b + c! //no error 

这是我不了解的:即使我将Chipid定义为char [2],我仍然可以将预期结果打印到日志中。

那是为什么? strcpy是否不应该为分配给Chipid的内存空间上溢,而只打印字符串的前2个字符?

3 个答案:

答案 0 :(得分:3)

  

这是我不了解的:即使我将Chipid定义为char [2],我   仍然可以将预期结果打印到日志中。

那么你很不幸。如果由溢出产生的未定义行为没有表现为其他数据的损坏,但是也没有使程序崩溃,则您特别幸运。行为是 undefined ,所以您不应解释它所依赖的任何表现形式,或者是语言指定的表现形式。

  

那是为什么?

该语言未指定会发生这种情况,当然也未指定在您的情况下会发生这种情况的原因。

在实践中,您观察到的清单就像strcpy将完整数据写入数组中从数组开始到结束为止的位置的内存中一样,覆盖了程序可能存储的所有内容在那个空间中,程序随后通过相应的溢出读取将其读回。

  

不应为Chipid分配分配的内存空间   由strcpy溢出,

是的

  

,并且仅字符串的前2个字符为   打印吗?

否,该语言未指定一旦程序通过执行缓冲区溢出(或其他方式)来执行UB,会发生什么情况。但也不是,C数组在内存中只是简单表示为连续的平面连续元素,没有明确的边界。这就是为什么C字符串需要终止的原因。字符串函数看不到包含字符串元素的数组的声明大小,它们只能看到元素序列。

答案 1 :(得分:2)

部分正确:“分配给Chipid的内存空间被strcpy溢出了”-这是事实。这就是为什么要得到完整结果的原因(嗯,溢出的结果是不确定的,并且可能是崩溃或其他结果)。

答案 2 :(得分:1)

当涉及到内存时,

C / C ++为您提供了很多功能。强大的力量带来巨大的责任。您正在执行的操作会带来不确定的行为,这意味着它可能会起作用。但是,当strcpy写入不应写入的内存时,肯定会在以后出现问题。

您会发现您可以摆脱C / C ++中的很多东西。但是,当您的程序意外崩溃时,此类事情会让您头疼,这可能在程序的整个不同部分中,这使得调试变得很困难。

无论如何,如果您使用的是C ++,则应使用std :: string,这样会使事情变得容易得多。