繁体   English   中英

为什么在这种情况下使用 memset

[英]Why use memset in this case

我从以前退休的开发人员那里继承了一些代码。 我的问题具体是在以下场景中使用 memset。 不是 c 程序员,我想知道为什么在这种特殊情况下使用 memset,下一行代码将值存储在 memset 刚刚设置为全 0 的变量中。 是否有理由在 strcpy 之前使用 memset?

switch(argc)
{
    case 1  :
        printf("\nCommand: %s \n",argv[0]);
       break;
    case 2  :
        memset(program_input_string,0,sizeof(program_input_string));
        strcpy(program_input_string,argv[1]);
        printf("\nCommand: %s [%s] \n",argv[0],argv[1]);
       break;
    default :
        printf("\nCommand: %s \n",argv[0]);
}

事实上,在这种情况下使用memset + strcpy的理由为零 事实上,如果程序员想要确保剩余的字节被清零,那么应该使用带有条件的strncpy来测试字符串是否完全适合缓冲区:

strncpy(program_input_string, argv[1], sizeof program_input_string);

// if the last character in the array is not '\0', it means that the
// string did not fit into the array in its entirety, and perhaps 
// the only sensible course of action is to abort the program...
if (program_input_string[sizeof program_input_string - 1] != '\0') {
    fputs("The argument was too long!", stderr);
    exit(1);
}

这有两个明显的优点:它不会将初始序列不必要地设置为零,并且它不会溢出输入缓冲区 - 如果缓冲区溢出发生,它将退出并显示合理的错误消息和退出代码。


因此,对“为什么使用这种结构”这个问题的明确答案将是非常常见的“程序员无能”。

可能是不必要的,但您应该在删除它之前仔细检查。

memset()确保终端\0之后的任何字节都被清零。 如果program_input_string始终被读取为字符串,并且代码在到达\0时始终停止,那么后面的内容并不重要。

如果有从整个缓冲区读取的代码(包括尾随字节),这可能会很有用。 例如,如果所有sizeof(program_input_string)字节都被复制到网络数据包中并通过网络发送,您就不想传输未初始化的字节。 在这种情况下,将缓冲区归零是值得的。

我想知道为什么在这种特殊情况下使用 memset,下一行代码将值存储在 memset 刚刚设置为全 0 的变量中。 是否有理由在 strcpy 之前使用 memset?

提供的特定memset()调用将目标数组的每个字节设置为 0。 strcpy()调用成功后,仅覆盖argv[1]字符串中的字节数,包括可能更少的终止符。 这种区别实际上对程序是否重要,无法从提供的代码中确定。

另请注意,所提供的代码可能会出现缓冲区溢出——它实际上是该问题的典型案例之一。 如果argv[1]目标数组长,则会出现未定义的行为。

在这种情况下,调用 memset 是多余的。 你可以写

strcpy(program_input_string,argv[1]);

因为 function strcpy 也会复制目标字符串中的终止零。

作为一个想法,有时一个字符数组需要包含几个字符串。 在这种情况下,两个连续的零表示存储在字符数组中的字符串集的结尾。 所以需要用零初始化数组。

假设数组program_input_string已经包含字符串

ABC\0DEF\0\0

那么如果复制字符串 E 你会得到

E\0C\0DEF\0\0

正如所见,结果不是预期的。 现在数组包含一组三个字符串而不是一个字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM