hex*_*079 28 c c++ buffer memory-management
可以理解的是,将缓冲区错误输出(或创建溢出),但如果12字节缓冲区中使用的字节少于12个,会发生什么?是否有可能或者空尾随时都是0?正交问题可能会有所帮助:缓冲区在实例化但未被应用程序使用时包含哪些内容?
我在Visual Studio中查看了几个宠物程序,似乎它们附加了0(或空字符),但我不确定这是否是一个可能因语言/编译器而异的MS实现.
sel*_*bie 17
采用以下示例(在代码块内,而不是全局):
char data[12];
memcpy(data, "Selbie", 6);
Run Code Online (Sandbox Code Playgroud)
甚至这个例子:
char* data = new char[12];
memcpy(data, "Selbie", 6);
Run Code Online (Sandbox Code Playgroud)
在上述两种情况下,前6个字节的data是S,e,l,b,i,和e.剩下的6个字节data被认为是"未指定的"(可以是任何东西).
是否有可能或者空尾随时都是0?
根本不保证.我所知道的唯一保证零字节填充的分配器是calloc.例:
char* data = calloc(12,1); // will allocate an array of 12 bytes and zero-init each byte
memcpy(data, "Selbie");
Run Code Online (Sandbox Code Playgroud)
缓冲区实例化但应用程序尚未使用时包含哪些内容?
从技术上讲,根据最新的C++标准,分配器提供的字节在技术上被认为是"未指定的".你应该假设它是垃圾数据(任何东西).不要对内容做任何假设.
使用Visual Studio进行调试构建通常会使用with 0xcc或0xcdvalues 初始化缓冲区,但在发布版本中不是这种情况.但是,对于Windows和Visual Studio,有一些编译器标志和内存分配技术可以保证零初始内存分配,但它不可移植.
Mat*_*her 11
C++具有存储类,包括全局,自动和静态.初始化取决于如何声明变量.
char global[12]; // all 0
static char s_global[12]; // all 0
void foo()
{
static char s_local[12]; // all 0
char local[12]; // automatic storage variables are uninitialized, accessing before initialization is undefined behavior
}
Run Code Online (Sandbox Code Playgroud)
一些有趣的细节在这里.
Age*_*t_L 11
考虑你的缓冲区,用零填充:
[00][00][00][00][00][00][00][00][00][00][00][00]
Run Code Online (Sandbox Code Playgroud)
现在,让我们写10个字节.值从1开始递增:
[01][02][03][04][05][06][07][08][09][10][00][00]
Run Code Online (Sandbox Code Playgroud)
现在再次,这次,4倍0xFF:
[FF][FF][FF][FF][05][06][07][08][09][10][00][00]
Run Code Online (Sandbox Code Playgroud)
如果在12字节缓冲区中使用少于12个字节会发生什么?是否有可能或者空尾随时都是0?
您可以根据需要进行编写,其余字节保持不变.
正交问题可能会有所帮助:缓冲区在实例化但未被应用程序使用时包含哪些内容?
未指定.预计之前使用此内存的程序(或程序的其他部分)会留下垃圾.
我在Visual Studio中查看了几个宠物程序,似乎它们附加了0(或空字符),但我不确定这是否是一个可能因语言/编译器而异的MS实现.
这正是你的想法.这次有人为你做过这件事,但不能保证它会再次发生.它可能是附加清理代码的编译器标志.某些版本的MSVC用于在调试中运行但不在发布时使用0xCD填充新内存.它也可以是一个系统安全功能,在将内存提供给您的进程之前擦除内存(因此您无法监视其他应用程序).永远记得在重要的地方使用memset初始化缓冲区.最终,如果您依赖新缓冲区来包含某个值,则在自述文件中使用某些编译器标志.
但清洁并不是必需的.你需要一个12字节长的缓冲区.你用7个字节填充它.然后你把它传递到某个地方 - 你说"这里有7个字节".从中读取缓冲区的大小无关紧要.您希望其他函数尽可能多地阅读,而不是尽可能多地阅读.实际上,在C语言中通常无法判断缓冲区的长度.
并附注:
可以理解的是,将缓冲区错误输出(或创建溢出)
它没有,这就是问题所在.这就是为什么它是一个巨大的安全问题:没有错误,程序试图继续,所以它有时执行它从未意图的恶意内容.因此,我们不得不向操作系统添加一堆机制,例如ASLR,这将增加程序崩溃的可能性并降低其继续损坏内存的可能性.因此,永远不要依赖那些事后的守卫并亲自观察你的缓冲区边界.
| 归档时间: |
|
| 查看次数: |
3358 次 |
| 最近记录: |