0

特定の char 配列を個別の文字列に分割しようとしています。これを行うには、各単語のアドレスを配列に入れ、アドレスから文字列を取得して出力します。

そのため、コードを更新しましたが、numArgs を出力した後、「test2」の前にプログラムがフリーズします。理由がわかりません。

----------------old code-----------------------   
char* parseArgs(char* comPtr){
    char *args[100] = {0};
    char *token;
    int i = 0;
    token = strtok(comPtr, " ");
    while(token != NULL){
        args[i] = malloc(100);
        args[i] = &token;
        token = strtok(NULL, " ");
    }
    return *args;
}

char* args = parseArgs(comPtr);
int i = 0;
while(i < numArgs){
    printf("arg%d: %s\n",i,&args[i]);
    i++;
}
-----------------------end old code--------------------

------------------new code------------------------
int countArgs(char* comPtr){
    char *token;
    int i = 0;
    token = strtok(comPtr, " ");
    while(token != NULL){
        i++;
        token = strtok(NULL, " ");
    }
    return i;
}

char** parseArgs(char* comPtr){
    printf("test1");
    char** args = calloc(100, sizeof(char*));
    char* token;
    int i = 0;
    while(token = strtok(comPtr, " ")){
        args[i] = token;
    }
    printf("test2");
    return args;
}

printf("ComPtr: %s\n",comPtr);
char* path = "/bin/";
//int pid = fork(); //pid always 0 so using pid = 1 to test
//printf("PID:%d",pid);
int pid = 1;
printf("PID:%d",pid);
if(pid != 0){
    int numArgs = countArgs(comPtr);
    printf("test1");
    printf("NumArgs: %d\n",numArgs);
    printf("test2");
    char** args = parseArgs(comPtr);
    int i = 0;
    printf("test3");
    while(i < numArgs){
        printf("arg%d: %s\n",i,args[i]);
        printf("test4");
        i++;
    }
}
else{
    //waitpid();
}
4

3 に答える 3

2

メモリがどこにあるか、ポインタが指しているかなどを見失っています。ポインタのリストをトークンに戻したい場合は、次のようなものが必要です。

char** parseArgs(char* comPtr){
    char** p_args = calloc(100, sizeof(char*);
    int i = 0;
    char* token;
    while (token = strtok(comPtr, " "))
        p_args[i] = token;
    return p_args;
}

char** p_args = parseArgs(comPtr);
int i = 0;
while(i < numArgs)
{
    printf("arg%d: %s\n",i,p_args[i]);
    i++;
}
free(p_args);

私はそれをテストしていませんが、それはあなたを正しい方向に向けるはずです。プログラムとの違いを慎重に検討し、コード内のデバッガーやprintf()ステートメントを使用してアドレスを出力し、どのように機能するかを確認します(または必要に応じてデバッグします)。

于 2013-03-08T06:36:47.130 に答える
0

フリーズは

int i = 0;
while(token = strtok(comPtr, " ")){
    args[i] = token;
}

ここで、無限ループで繰り返し、の最初のトークンを見つけ、comPtr各反復で(文字列がスペースで始まらない限り)にtokenなり&comPtr[0]、それがに割り当てられargs[i]ます。

最初の呼び出しの後、それへのすべての呼び出しstrtokは、同じ文字列内にさらにトークンを見つける必要があります(存在する場合) NULL。最初の引数が必要です。

また、おそらく新しいトークンごとiに上書きしたくないので、おそらくループ内でインクリメントする必要があります。args[0]

于 2013-03-08T12:16:43.143 に答える
0

ポインター配列 'char *args[100]' をグローバル変数として宣言します。プログラムでは、メモリをローカル ポインターに割り当てており、その寿命は関数内にあります。そのため、関数の最後でポインター変数のスコープが終了します。ここにもメモリリークがあります。

于 2013-03-08T06:30:46.907 に答える