删除缓冲区时,strcpy_s导致“检测到堆错误”错误

3gtaxfhh  于 2023-01-01  发布在  其他
关注(0)|答案(1)|浏览(122)
char* buf = (char*)malloc(sizeof(char) * 11);
    for (int i = 0; i < 5; i++)
        buf[i] = '?';
    strcpy_s(buf + 5, sizeof(char) * 11, "apple");
    buf[10] = '\0';
    printf(buf);
    free(buf);

我有上面的代码。当buf被释放时,它说“heap corruction detected”。我想使用strcpy_s写入buf的最后5个字符。根据我的阅读和理解,size参数应该是目标缓冲区的大小,但我也尝试这样做
第一个月
但在这种情况下,它说缓冲区太小了,我该怎么办?

nhaq1z21

nhaq1z211#

strcpy_s(buf + 5, sizeof(char) * 11, "apple");告诉strcpy_sbuf + 5处有11个字节可用。buf指向的位置预留了11个字节,从buf + 5开始,只有6个字节可用。
这个strcpy_s会溢出数组并写入其他内存,从而破坏所谓的堆。原因是,尽管人们可能认为strcpy_s会复制单个字节,直到看到终止的空字符,但例程的规范允许它使用整个目标缓冲区,而不管源字符串的长度。具体来说,C 2018 K.3.7.1.4 5指出:
strncpy_s返回非零值时,s1指向的s1max字符数组中strncpy_s写入的终止空字符(如果有)后面的所有元素将取未指定的值。
这样做的目的是允许strncpy_s的优化实现复制比单个字节更大的数据组。
(One我可能想知道,当复制这样的数据组时,如何避免在源数组中溢出终止空值。对此的答案是,在常见的C实现中,复制对齐的字是安全的,因为存储器保护以页对齐的单位操作。因此,strcpy_s实现可以将整个对齐的字从源复制到目标,只要它们适合目标且不为空字符尚未在单词中看到。)

相关问题