1

を返す必要がありますchar**が、これを行おうとすると、ローカル変数のアドレスを返すようにコンパイラから指示されます。どうやってやるの?この変数にスペースを割り当てる必要があることはわかっていますが、どうすればよいでしょうか? これが私のコードですが、2番目printfは表示されず、関数は何も返しません:

char** parse_cmd(const char* cmdline) {
char** arguments = (char**)malloc(100);
int i;
int j=0, k=0;
printf("%s\n", cmdline);

for(i=0; i<100; i++) {
    arguments[i] = malloc(100);
}

for(i = 0; i < strlen(cmdline); i ++) {
    if(cmdline[i] != ' ') {
        arguments[j][k] = cmdline[i];
        k++;
    } else {
        arguments[j][k] = '\0';
        j++;
        k = 0;
    }
}

printf("%s\n", arguments[1]);

return arguments;
}
4

2 に答える 2

4

複数の割り当てを行う必要があります。最初はchar**、次に のそれぞれですchar*。たとえば、次のようなもの

  char **args = (char**)malloc(100);
  int i;
  for (i=0; i<100; i++) 
    args[i] = malloc(100);

  // Rest of program

  return args;
于 2011-05-30T05:03:51.413 に答える
2

これが私が組み立ててテストしたコードです。argvアセンブル時に、引数リストと各引数の両方に動的メモリ割り当てを使用します。この関数release_cmd()は、割り当てられたスペースを解放します。この関数cleanup()は内部的なものであり、失敗すると割り当てられた領域を解放してから、null 二重ポインターを返します。これにより、エラー処理が簡素化されます。prompt()関数とには最小限のテスト ハーネスがありますmain()。の下で実行したことはありませんvalgrindが、MacOS X の実装ではmalloc()問題が頻繁に検出されるため、重大なメモリの乱用はないとある程度確信していますが、オフバイワン リークが発生する可能性があります。cleanup()割り当ての失敗を偽ってコードをテストしていません。

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

void release_cmd(char **argv)
{
    for (size_t i = 0; argv[i] != 0; i++)
        free(argv[i]);
    free(argv);
}

static char **cleanup(size_t argc, char **argv)
{
    argv[argc] = 0;
    release_cmd(argv);
    return 0;
}

char **parse_cmd(const char* cmdline)
{
    size_t argc = 2;
    char **argv = malloc(argc * sizeof(char *));

    if (argv == 0)
        return 0;

    size_t j = 0;  // Index into argv
    size_t len = strlen(cmdline);

    for (size_t i = 0; i < len; i++)
    {
        while (isspace(cmdline[i]))
            i++;
        if (cmdline[i] == '\0')
            break;
        if (j > argc - 2)
        {
            size_t newc = (argc * 2);
            char **newv = realloc(argv, newc * sizeof(char *));
            if (newv == 0)
                return cleanup(argc, argv);
            argv = newv;
            argc = newc;
        }
        size_t argl = 2;    // Length of argument string
        argv[j] = malloc(argl);
        size_t k = 0;       // Index into argv[j]
        while (cmdline[i] != '\0' && !isspace(cmdline[i]))
        {
            if (k > argl - 2)
            {
                size_t newl = argl * 2;
                char  *news = realloc(argv[j], newl);
                if (news == 0)
                    return cleanup(argc, argv);
                argv[j] = news;
                argl    = newl;
            }
            argv[j][k++] = cmdline[i++];
        }
        argv[j][k] = '\0';
        argv[j] = realloc(argv[j], k+1);    // Shrink to fit!
        j++;
    }
    argv[j] = 0;
    argv = realloc(argv, (j+1)*sizeof(*argv));  // Shrink to fit!

    return argv;
}

static int prompt(const char *prompt, char *buffer, size_t bufsiz)
{
    printf("%s", prompt);
    return (fgets(buffer, bufsiz, stdin) != 0);
}

int main(void)
{
    char line[1024];

    while (prompt("cmd? ", line, sizeof(line)) != 0)
    {
        char **argv = parse_cmd(line);
        char **args = argv;
        while (*args)
            puts(*args++);
        release_cmd(argv);
    }
    putchar('\n');
    return 0;
}
于 2011-05-30T06:45:26.533 に答える