我观察到 Microsoft 实现的一个有趣的问题strncat
。它触及源缓冲区之外的 1 个字节。考虑以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
void main()
{
char dstBuf[1024];
char* src = malloc(112);
memset(src, 'a', 112);
dstBuf[0] = 0;
strncat(dstBuf, src, 112);
}
strncat
在 112 字节块之后读取 1 个字节。因此,如果您不幸在无效页面边界上获得分配,您的应用程序就会崩溃。大型应用程序可能会在这些地方间歇性地崩溃。(请注意,可以使用gflags PageHeap设置来模拟这种情况;块大小必须能被指针大小整除才能正确对齐。)
这是预期的行为还是错误?有什么链接可以确认吗?(我阅读了一些描述,strncat
但可以根据您最初的想法来解释它们的两种方式......)
更新(回答有关证据的问题):如果从上面的文字中不清楚,我很抱歉,但这是一个实验事实。strncat
我在读取地址 src+srcBufSize的应用程序中观察到间歇性崩溃。在这个使用gflags PageHeap运行的小示例中,崩溃时始终重现 (100%)。因此,据我所知,证据非常确凿。
Update2(编译器信息)MS Visual Studio 2005 版本 8.0.50727.867。构建平台:64 位版本(32 位无复制)。用于重现崩溃的操作系统:Windows Server 2008 R2。
更新 3使用 MS Visual Studio 2012 11.0.50727.1 中内置的二进制文件也会重现该问题
更新 4 链接以在 Microsoft Connect 上发布;链接到 MSDN 论坛上的讨论
更新 5该问题将在下一个 VS 版本中修复。没有计划对旧版本进行修复。请参阅上面的“Microsoft Connect”链接。