![]() |
1
4
这是一个有趣的问题,我们都希望在某种程度上理解。此处出现的问题称为: 缓冲区溢出 该问题的副作用可能因系统而异(也称为 未定义行为 ). 为了向您解释可能发生的情况,让我们假设程序中变量的内存布局如下所示
注:上述表示仅用于理解,不显示任何架构的实际表示。 执行strncpy命令后,该内存区域的内容如下:
现在,当您打印buff时,您可以看到buf的起始地址中现在有“h”。printf开始打印,直到它找到一个超过buff内存区域的空字符。因此,当您打印buf时,会得到“his is String”。 但是,请注意,由于堆栈保护(依赖于系统/实现),程序1不会生成堆栈破坏错误。因此,如果您在不包含此代码的系统上执行此代码,程序1也将崩溃(您可以通过将Str增加为长字符串来测试)。 在程序2的情况下,strncpy只是在从main写入返回地址时通过堆栈保护,因此会发生崩溃。 希望这有帮助。 P、 所有上述描述都是为了理解,没有显示任何实际的系统表示。 |
![]() |
2
3
C标准规定:
这些语义被广泛误解:
在您的示例中
您可以看到,这是第一个示例,因为
我的建议是: 切勿使用此功能 .其他C专家如布鲁斯·道森的观点: Stop using strncpy already! 您应该喜欢一个不太容易出错的函数,例如:
您可以在示例中这样使用它:
|
![]() |
3
0
你的
但正如我之前所说,如果使用不同的编译器,甚至同一编译器的不同版本,您可能会得到完全不同的行为。
总结:永远不要做任何调用未定义行为的事情。在里面
|
![]() |
4
0
什么时候
这是未定义的行为(将更多数据写入
未定义性质的例子是,由于没有金丝雀,程序可能因“非法指令@xxxxxx”而崩溃。 如果返回地址与变量位置分开,程序可能表现正常。
在大多数当前CPU上,堆栈通常会沿负方向增长。此外,dest vs buff的位置取决于编译器。它可能已将它们切换到原来的位置,或者(例如)您删除了第二个printf,编译器可能已删除了
|
![]() |
payloc91 · 存储地图中的条目是否安全?它会导致内存泄漏吗? 6 年前 |
![]() |
pjj · 如果GC'ed是弱可达对象,那么为什么会出现OOM错误 6 年前 |
![]() |
K.R. · RxJava行为主体和使用者-这里是否存在内存泄漏? 6 年前 |
![]() |
eaglefreeman · 意外的R内存管理行为 6 年前 |
![]() |
areify · 如何避免此代码中的内存泄漏? 6 年前 |