0

使用 memset() 初始化缓冲区然后使用不同的调用向其中添加特定数据是否有效?

例子:

        DIR *dirp;
        struct dirent *dp;
        struct dirent *buf;

        dirp = opendir("/dev");
        if( dirp ) {
            buf = (struct dirent *)malloc(offsetof(struct dirent, d_name) + NAME_MAX + 1);
            if (buf == NULL) {
                closedir( dirp );
                return = ENOMEM;
            }
            while( readdir_r(dirp, buf, &dirp) == 0 && dirp ) {
                if( strncmp( dp->d_name, "video", 5 ) == 0 ) {
                    char vidpath[21];
                    memset( vidpath, 0x0, sizeof( vidpath ) );
                    snprintf( vidpath, 20, "/dev/%s", dp->d_name );

                    // Now do an operation that prints the buffer...

                }
            }
            free ( buf );
            closedir( dirp );
        }

问候

4

3 回答 3

1

通过避免动态分配,程序可以大大简化(astruct dirent有一个小的固定大小:名称加上几个整数)vidbuf不需要比 PATH_MAX 长(但如果内存非常紧张,你可以使用预先计算的值,比如 20 , 并测试 snprintf() 的返回值)

#include <stdio.h>
#include <string.h>
#include <dirent.h>

void do_stuff(char * dev);
void do_stuff(char * dev)
{
DIR *dirp;
struct dirent entbuf, *dp;
char vidpath[ PATH_MAX ];

        dirp = opendir(dev);
        if (!dirp ) return;

        while ( !readdir_r(dirp, &entbuf, &dp) ) {
                if ( !dp ) break;
                if ( memcmp( dp->d_name, "video", strlen("video")  ) ) continue;
                snprintf( vidpath,sizeof vidpath, "%s/%s", dev, dp->d_name );

                    // Now do an operation that prints the buffer...
                fprintf(stderr, "Yes: %s\n", vidpath );

            }
        closedir( dirp );
}

int main(void)
{

do_stuff ( "/dev" );

return 0;
}
于 2013-06-16T14:24:50.220 回答
0

memset将内存初始化为给定值,因此确保没有不必要的副作用绝对是有效且良好的做法。由于您无论如何都在使用 snprintf,但它并不是绝对必要的,因为您传递的是 size-1,所以 memset 在循环中不应该是必需的。

不过,您也应该使用sizeof(vidpath)for snprintf 。

 snprintf( vidpath, sizeof(vidpath), "/dev/%s", dp->d_name );
于 2013-06-16T12:11:42.747 回答
0

首先要注意:

char vidpath[21];
memset( vidpath, 0x0, sizeof( vidpath ) );

可以写成:

char vidpath[21] = {0};

但当然,memset按照您的方式调用是有效的。

现在,当您调用snprintf时,没有必要先初始化缓冲区。

也代替:

snprintf( vidpath, 20, "/dev/%s", dp->d_name );

你可以写

snprintf( vidpath, 21, "/dev/%s", dp->d_name );

或更好

snprintf( vidpath, sizeof vidpath, "/dev/%s", dp->d_name );

一如既往snprintf地写入空终止符(除非指定的最大大小为0)。

于 2013-06-16T12:14:16.383 回答