使用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 );
}
此致
答案 0 :(得分:1)
通过避免动态分配可以简化程序(struct 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;
}
答案 1 :(得分:0)
memset
将内存初始化为给定值,因此它是无效的,并且是确保没有不良副作用的良好做法。既然你正在使用snprintf,那么它并不是严格必要的,因为你传递的是size-1,所以memset在循环中不是必需的。
你也应该使用sizeof(vidpath)
来获取snprintf。
snprintf( vidpath, sizeof(vidpath), "/dev/%s", dp->d_name );
答案 2 :(得分: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
)。