2013-06-16 2 views
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); 
     } 

С уважением

ответ

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; 
} 
0

memset инициализирует память до заданного значения, так что Defintely действует и хорошая практика, чтобы убедиться, что нет никаких нежелательных побочных эффектов. Так как вы используете snprintf в любом случае, это не будет строго необходимо, поскольку вы передаете размер 1, поэтому memset не должен быть необходим в цикле.

Вы также должны использовать sizeof(vidpath) для snprintf.

snprintf(vidpath, sizeof(vidpath), "/dev/%s", dp->d_name); 
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).

Смежные вопросы