我有以下程序:(功能:在字符串右侧填充空格,这里使用 astreix 以方便视觉):
操作系统:Windows( Visual Studio )
#include "stdafx.h"
#include<stdlib.h>
#include<string.h>
#define CBUFFSIZE 48
void right_pad_str(char *pad_str, char *buff,int max_buffsize){
int padstr_len = 0;
int space_len = 0;
char *end_str = NULL;
memset(buff, '\0', max_buffsize);
padstr_len = strlen(pad_str);
space_len = ((max_buffsize - 1) - padstr_len);
strncpy_s(buff, max_buffsize, pad_str, strlen(pad_str));
end_str = buff +padstr_len;
memset((end_str), '*', space_len);
buff[max_buffsize] = '\0';
}
int _tmain(int argc, _TCHAR* argv[]){
char tmpstr[49] = { '\0' };
char *str = "hello_world";
right_pad_str(str, tmpstr, CBUFFSIZE + 1);
return 0;
}
当我查看 memeset 后的值时,memset 似乎有问题,它看起来非常不正确,即垃圾为什么会这样?最后我 null 终止字符串但我看到垃圾值和堆栈损坏错误,不是确定我的逻辑有什么问题。
(我附上了相同的快照)
最佳答案
在这个更简单的例子中可以看到意想不到的行为:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buffer[3];
buffer[0] = '\0';
buffer[1] = '\0';
buffer[2] = '\0';
strncpy_s(buffer, 3, "*", 1);
printf("%u\n", (unsigned int)(unsigned char)buffer[2]);
return 0;
}
输出是 254 而不是 0,但仅在调试版本中。这发生在调用 strncpy_s
的过程中,它意外地写入了复制末尾之后的目标缓冲区,大概是为了暴露代码中的错误,例如(已经指出的)错误。
注意: Retired Ninja 非常正确地指出(在对问题的评论中),这在 the documentation's 中描述得有点不准确。细则,我最初忽略了这一点:
The debug versions of these functions first fill the buffer with 0xFD. To disable this behavior, use _CrtSetDebugFillThreshold.
(事实上,至少在 Visual Studio 2010 中,它用 0xFE 填充缓冲区。)
关于c - 为什么 memset 没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45991954/