我认为我没有正确理解如何为我想做的事情分配内存。
我希望我的程序将命令行中的参数存储到名为Command的stuct数组中,其中包含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吗?这是我的代码:
#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;
}
答案 0 :(得分:1)
您的数据存储结构无法告知commands[j]
中有多少字符串有效。所以我认为它正在commands[0]
和commands[1]
分别提出两个指针,就像你期望的那样。但是,然后你的打印循环会查看commands[0].args[k]
的k一直到4,尽管它只对前两个有效。当你开始查看commands[0].args[2]
时,结果是未定义的。 (如果您使用未定义的行为,则显示程序中其他位置的内存,崩溃和着火只是程序允许执行的一些操作。)
要确定每个命令中有多少个参数,您可以向struct test
添加一个计数器成员。或者可能再分配一个指针而不是参数,并在最后一个参数后面加上一个NULL。
答案 1 :(得分:0)
您的每个Command
结构只有一个arg
也许你应该考虑
typedef struct test {
char **args[5];
} Command;
然后设计一个更好的数据结构,如列表列表。
答案 2 :(得分:0)
也许你应该在结构中存储args的长度?
typedef struct test {
char ** args;
unsigned length;
} Command;
另外,也许你应该考虑使用C字符串库的一些内置功能。例如,strtok使用您提供的分隔符拆分字符串。
答案 3 :(得分:0)
以下是我如何分配内存:
#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;
}