簡體   English   中英

有人可以幫助我了解如何在c中正確分配嗎?

[英]Can someone help me understand how to allocate properly in c?

我認為我沒有正確理解如何為我想做的事情分配內存。

我希望程序將命令行中的參數存儲到名為Command的結構數組中,該結構中包含char ** args。 例如,如果我跑步

./test.c echo hello : ls -l

我希望它以此存儲

commands[0].args[0]= echo
commands[0].args[1]= hello
commands[1].args[0]= ls
commands[1].args[1]= -l

但是我的代碼以這種方式存儲它

commands[0].args[0]= echo
commands[0].args[1]= hello
commands[0].args[2]= ls
commands[0].args[3]= -l
commands[1].args[0]= ls
commands[1].args[1]= -l

有人可以幫助我了解為什么將ls -l存儲在2個地方嗎? 這是我的代碼:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct test {
   char **args;
} Command;


int main(int argc, char *argv[])
{
   int i, j, k;
   Command *commands;

   j = k = 0;
   commands = (Command *)malloc(argc * sizeof(Command));

   for (i = 1; i < argc; i++)
   {
      if (strcmp(argv[i], ":") == 0)
      {
         j++;
         k = 0;
      }
      else {
         commands[j].args = (char **)realloc(commands[j].args, (k+1) * sizeof(char*));
         commands[j].args[k++] = argv[i];
      }
   }

   for (i = 0; i <= j; i++)
   {
      for (k = 0; k < 5; k++)
      {
         printf("commands[%d].args[%d]= %s\n", i, k, commands[i].args[k]);
      }
   }
   return EXIT_SUCCESS;
}

您的數據存儲結構無法確定commands[j]有多少個字符串有效。 因此,我認為它正像您期望的那樣,在commands[0]commands[1]分別放置兩個指針。 但隨后,您的打印循環將commands[0].args[k]一直查找到4,盡管僅查看前兩個有效。 當您開始查看commands[0].args[2] ,結果是不確定的。 (如果您使用未定義的行為,則從程序中其他地方顯示內存,崩潰和着火只是允許程序執行的一些操作。)

要弄清楚每個命令中有多少個參數,您可以在struct test添加一個計數器成員。 或者分配的指針多於參數個數,並在最后一個參數后放置一個NULL。

您的每個Command結構只有一個arg

也許你應該考慮

typedef struct test {
   char **args[5];
} Command;

然后設計一個更好的數據結構,例如列表列表。

也許您應該將args的長度存儲在結構中?

typedef struct test {
    char ** args;
    unsigned length;
} Command;

另外,也許您應該考慮使用C字符串庫的某些內置功能。 例如, strtok使用給定的定界符分割字符串。

這是我分配內存的方式:

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

typedef struct cmd_s {
    int num;
    char **args;
} cmd_t;

void print_cmds(cmd_t *c, int num) {
    int i, j;
    for (i=0;i<=num;i++) {
        for (j=0;j<c[i].num;j++)
            printf("cmds[%d][%d] = %s\n", i, j,c[i].args[j]);
    }
}

int main(int argc, char *argv[]) {
    int i, j = 0, k = 0;
    cmd_t *cmds;

    cmds = (cmd_t *)malloc(sizeof(cmd_t));
    cmds[0].args = NULL;
    cmds[0].num = 0;

    for (i=1;i<argc;i++) {
        if (strcmp(argv[i], ":") == 0) {
            cmds = (cmd_t *)realloc(cmds, (sizeof(cmd_t) * ++j) + 1);
            cmds[j].args = NULL;
            cmds[j].num = 0;
            continue;
        }
        cmds[j].args = (char **)realloc(cmds[j].args, sizeof(char *) * ++cmds[j].num);
        cmds[j].args[cmds[j].num-1] = (char *)malloc(50);
        strcpy(cmds[j].args[cmds[j].num-1], argv[i]);
    }

    print_cmds(cmds, j);

    for (i=0;i<=j;i++) {
        for(k=0;k<cmds[i].num;k++)
            free(cmds[i].args[k]);
        free(cmds[i].args);
    }

    free(cmds);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM