简体   繁体   English

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

[英]Why use memset in this case

I have inherited some code from a previous developer that has retired.我从以前退休的开发人员那里继承了一些代码。 My question is specifically the use of memset in the following scenario.我的问题具体是在以下场景中使用 memset。 Not being a c programmer, I am wondering why memset was used in this particular case, where the next line of code stores the value in the variable that was just set to all 0 by memset.不是 c 程序员,我想知道为什么在这种特殊情况下使用 memset,下一行代码将值存储在 memset 刚刚设置为全 0 的变量中。 Is there a reason to use memset right before strcpy?是否有理由在 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]);
}

The truth is there is zero reason to use memset + strcpy in this case.事实上,在这种情况下使用memset + strcpy的理由为零 In fact if the programmer wanted to ensure that the remaining bytes were zeroed, then strncpy with a conditional for testing if the string fit in entirety into the buffer should have been used:事实上,如果程序员想要确保剩余的字节被清零,那么应该使用带有条件的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);
}

This has two obvious advantages: it does not set the initial sequence to zero needlessly and it cannot overrun the input buffer - and if the buffer overrun were to happen it will exit with a sensible error message and exit code.这有两个明显的优点:它不会将初始序列不必要地设置为零,并且它不会溢出输入缓冲区 - 如果缓冲区溢出发生,它将退出并显示合理的错误消息和退出代码。


Thus the definite answer to the question "why was this construct used" would be the all-too-common "programmer incompetence".因此,对“为什么使用这种结构”这个问题的明确答案将是非常常见的“程序员无能”。

It's probably unnecessary, but you should check carefully before you delete it.可能是不必要的,但您应该在删除它之前仔细检查。

The memset() ensures that any bytes after the terminal \0 are zeroed out. memset()确保终端\0之后的任何字节都被清零。 If program_input_string is always read as a string and code always stops when it hits \0 then what comes after doesn't matter.如果program_input_string始终被读取为字符串,并且代码在到达\0时始终停止,那么后面的内容并不重要。

It could be useful if there's code that reads from the entire buffer, trailing bytes included.如果有从整个缓冲区读取的代码(包括尾随字节),这可能会很有用。 For example, if all sizeof(program_input_string) bytes were copied into a network packet and sent over the wire you wouldn't want to transmit uninitialized bytes.例如,如果所有sizeof(program_input_string)字节都被复制到网络数据包中并通过网络发送,您就不想传输未初始化的字节。 In that case, zeroing out the buffer would be worthwhile.在这种情况下,将缓冲区归零是值得的。

I am wondering why memset was used in this particular case, where the next line of code stores the value in the variable that was just set to all 0 by memset.我想知道为什么在这种特殊情况下使用 memset,下一行代码将值存储在 memset 刚刚设置为全 0 的变量中。 Is there a reason to use memset right before strcpy?是否有理由在 strcpy 之前使用 memset?

The particular memset() call presented sets every byte of the destination array to 0. The strcpy() call, when successful, overwrites only as many bytes as are in the argv[1] string, including the terminator, which may be fewer.提供的特定memset()调用将目标数组的每个字节设置为 0。 strcpy()调用成功后,仅覆盖argv[1]字符串中的字节数,包括可能更少的终止符。 Whether this distinction is in fact important to the program is impossible to determine from the code presented.这种区别实际上对程序是否重要,无法从提供的代码中确定。

Note also that the code presented is subject to buffer overrun -- it is in fact an example of one of the canonical cases for that issue.另请注意,所提供的代码可能会出现缓冲区溢出——它实际上是该问题的典型案例之一。 If argv[1] is longer than the destination array then undefined behavior ensues.如果argv[1]目标数组长,则会出现未定义的行为。

In this case the call of memset is redundant.在这种情况下,调用 memset 是多余的。 You may just write你可以写

strcpy(program_input_string,argv[1]);

because the function strcpy copies also the terminating zero in the destination string.因为 function strcpy 也会复制目标字符串中的终止零。

As an idea sometimes a character array need to contain several strings.作为一个想法,有时一个字符数组需要包含几个字符串。 In this case two consequitive zeroes mean the end of the set of strings stored in the character array.在这种情况下,两个连续的零表示存储在字符数组中的字符串集的结尾。 So it is required to initialize the array with zeroes.所以需要用零初始化数组。

Let's assume that the array program_input_string already contains strings假设数组program_input_string已经包含字符串

ABC\0DEF\0\0

then if to copy string E you will get那么如果复制字符串 E 你会得到

E\0C\0DEF\0\0

As it is seen the result is not what was expected.正如所见,结果不是预期的。 Now the array contains a set of three strings instead of one string.现在数组包含一组三个字符串而不是一个字符串。

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

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