Получение длины одной строки в двумерном динамически распределенном массиве строк - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь найти все группы, к которым принадлежит пользователь в моей системе UNIX, и что для каждого пользователя. Реализация должна быть в C. Вот мой код:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>


static void error_fatal(char* msg) 
{ perror(msg); exit(EXIT_FAILURE); }

int main(int argc, char** argv) {

    struct group* grp;
    struct passwd* pwd;
    char *name;
    int i = 0;

    setpwent();

    while((pwd = getpwent()) != NULL){

        if(  ( name = (char*) malloc( (strlen(pwd->pw_name)+1)*sizeof(char))) == NULL  ) error_fatal("malloc");
        strcpy(name, pwd->pw_name);
        printf("%s:\n", name); 

        setgrent();
        while( (grp = getgrent()) != NULL ) {
            for( i=0; i < (sizeof(grp->gr_mem)/sizeof(grp->gr_mem[0])); i++ ){
                if( /*strlen(&grp->gr_mem[i][0]) == strlen(name) && */ !strcmp(grp->gr_mem[i], name) )
                     printf("%s\n", name);
}                           }

        endgrent(); 
        free(name);

}
    endpwent();

    return 0;
}

Но я получаюошибка сегментации после вывода «root:».Я почти уверен, что проблема в доступе к списку членов в четвертом поле файла / etc / group (подробности см. В man 5 group).

Итак, в основном моя проблема заключается в том, чтобы выяснить, сколькочлены каждой группы, поэтому мой счетчик (я в программе, последний цикл for) будет иметь хорошую верхнюю границу.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Выполнение вашего кода Я обнаружил, что ваша проблема не проверяет grp->gr_mem[i] == NULL перед его использованием в strcmp вызове:

if (grp->gr_mem[i] == NULL)
  continue;

Добавление этих строк до того, как вызов strcmp сработает дляя.

Кроме того, не забудьте освободить память, которую вы используете.Я не знаю, является ли это вашим полным кодом, но здесь вы должны рассмотреть возможность использования free(name) в вашем цикле while.

0 голосов
/ 07 декабря 2018

Ваша проблема здесь:

for( i=0; i < (sizeof(grp->gr_mem)/sizeof(grp->gr_mem[0])); i++ ){

struct group определяется как:

       struct group {
           char   *gr_name;        /* group name */
           char   *gr_passwd;      /* group password */
           gid_t   gr_gid;         /* group ID */
           char  **gr_mem;         /* NULL-terminated array of pointers
                                      to names of group members */
       };

Вы предполагаете, что gr_mem - это массив, но это не так.Это указатель, указывающий на первый элемент массива.Так что sizeof(grp->gr_mem)/sizeof(grp->gr_mem[0]) дает вам размер указателя, вероятно, 8 в вашей системе.Поэтому, если у пользователя менее 8 групп, вы закончите чтение за концом массива gr_mem указывает на начало.

Поскольку массив, на который указывает gr_mem, завершается NULL,обнаружение этого терминатора говорит вам, когда цикл завершен:

for( i=0; grp->gr_mem[i]; i++ ){
...