返回指向结构的指针,该结构中有一个指向char **指针的结构

时间:2015-10-25 08:06:29

标签: c pointers struct return-type

我只是无法理解,我应该如何返回一个包含双指针的结构....当我尝试它在同一个函数中打印正确的值...但是当我打印后打印垃圾值把它归还给主...

struct arguments{
char **argv;
int argc;
};

这是结构。

struct arguments * shell_make_argu(char *line)
{
   struct arguments *data=malloc(sizeof(struct arguments));
   int bufsize = word_BUFSIZE , i;
   data->argc = 0;
   data->argv = malloc(bufsize * sizeof(char*));
   char *word;

  if (!data->argv) {
    fprintf(stderr, "shell memory allocation error\n");
    exit(EXIT_FAILURE);
 }

word = strtok(line, word_separater);
while (word != NULL) {
    data->argv[data->argc] = word;
    data->argc++;

    if (data->argc >= bufsize) {
      bufsize += word_BUFSIZE;
      data->argv = realloc(data->argv, bufsize * sizeof(char*));
      if (!data->argv) {
        fprintf(stderr, "shell memory allocation error\n");
        exit(EXIT_FAILURE);
      }
    }

    word = strtok(NULL, word_separater);
}
data->argv[data->argc] = NULL;
for(i=0;i<data->argc;i++)
    printf("Command was: %s\n",data->argv[i]);
return data;
}

这就是我在main中接收结构的方式....

int main(int argc,char **argv)
{
struct arguments *data = malloc(sizeof(struct arguments));
char *line;
int status = 1 , i;
do {
    printf("T_Shell>> ");                           
    line = shell_take_input();                     
    if(line != '\0' && strcmp(line,"found ctrl_D") != 0){
        data = shell_make_argu(line);
        free(line);
        for(i=0;i<data->argc;i++)
            printf("Command was: %s\n",data->argv[i]);
        shell_execute_comand(data->argc,data->argv);
    }
    else if(line == '\0')
        printf("\n");
    else
        break;
 } while (status);
 system("clear");
 return 0;
}

2 个答案:

答案 0 :(得分:1)

free函数中打印line之前,您data->argv执行了main,这很糟糕,因为data->argv的每个元素都指向指向的缓冲区line

调用free后执行shell_execute_comand,或分配新内存并复制strtok返回的字符串,而不是将strtok的返回值直接分配给元素data->argv

答案 1 :(得分:0)

shell_make_argu()函数:

struct arguments* shell_make_argu(char *line)
{
   struct arguments *data = malloc(sizeof(struct arguments));
   int bufsize = word_BUFSIZE , i;

   data->argc = 0;
   data->argv = malloc(bufsize * sizeof(char*));

   char *word;

   if (!data->argv) 
   {
       fprintf(stderr, "shell memory allocation error\n");
       exit(EXIT_FAILURE);
   }

   word = strtok(line, word_separater);
   while (word != NULL) 
   {
       if (data->argc == bufsize)  <-- Moved realloc at beginning of loop
       {
           bufsize += word_BUFSIZE;
           data->argv = realloc(data->argv, bufsize * sizeof(char*));
           if (!data->argv) 
           {
               fprintf(stderr, "shell memory allocation error\n");
               exit(EXIT_FAILURE);
           }
       }

       data->argv[data->argc] = malloc(strlen(word)+1);  <-- Added allocation of argv[argc] char pointer
       strcpy(data->argv[data->argc], word);   <-- Added storing token

       data->argc++;

       word = strtok(NULL, word_separater);
   }

   //data->argv[data->argc] = NULL;   <-- Not required, can be removed
   for(i=0;i<data->argc;i++)
       printf("Command was: %s\n",data->argv[i]);

    return data;
}

main()函数:

int main(int argc, char **argv)
{
    struct arguments *data;  <-- Removed malloc, make_shell_argu() returns allocated pointer
    char *line;
    int status = 1 , i;
    do 
    {
        printf("T_Shell>> ");                           
        line = shell_take_input();                     
        if(line != NULL && strcmp(line,"found ctrl_D") != 0)  <-- Changed condition check with (line != NULL)
        {
            data = shell_make_argu(line);
            free(line);

            for(i=0;i<data->argc;i++)
                printf("Command was: %s\n",data->argv[i]);

            shell_execute_comand(data->argc,data->argv);

            for(i=0;i<data->argc;i++)  <-- Added memory releasing code
            {
                free(data->argv[i]);
            }
            free(data->argv);
            free(data);                 <-- Freeing 'data' also, make_shell_argu() will return new allocated pointer next time
        }
        else if(line == NULL)  <-- Changed condition check to (line == NULL)
        {
            printf("\n");
        }
        else
        {
            status = 0;
        }
    } while (status);

    system("clear");

    return 0;
}