2017-09-30 2 views
0

私のコードを実行すると、最初のprintParams()呼び出しは完全に機能します。しかし、fork()の後のすべての呼び出しでは、の配列値はすべて失われます。私はポインターをよく知っているわけではありませんが、この問題の根本はおそらくポインタベースであることがわかります。たとえば、最初のprintParams()は、Parse()関数で割り当てられたすべての値を出力します。しかし、fork()の後には、backgroundargumentCountのような整数値はすべて表示されますが、inputRedirectに関連付けられた文字列値、またはvectorArguments配列に保持されている文字列値は表示されません。私はCでシェルを書いていますが、構造体のchar配列へのポインタに問題があります

Here is a photo of my ouput]

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include "parse.h" 

void printParams(Param_t * param); 

struct PARAM 
{ 
    char *inputRedirect;   /* file name or NULL */ 
    char *outputRedirect;   /* file name or NULL */ 
    int background;    /* ethier 0 (false) or 1 (true) */ 
    int argumentCount;    /* number of tokens in arguement vector 
    */ 
    char *argumentVector[MAXARGS]; /* array of String */ 
}; 

typedef struct PARAM Param_t; 

int main(int argc, char *argv[]){ 
    int i; 
    int debug; 
    pid_t pid; 

    if(argc>1){ 
     if(!strcmp(argv[1], "-debug")) 
      debug = 1; 
    } 

    Param_t * testParam = Parse(); 

    if(debug == 1){ 
     printParams(testParam); 
    } 

    pid = fork();  
    printParams(testParam); 

    if(pid == 0){ 
     exit(1); 
    }  
    return 0; 
} 

void printParams(Param_t *param) 
{ 
    int i; 

    printf("InputRedirect: [%s]\n", (param->inputRedirect != NULL) ? param- 
    >inputRedirect: "NULL"); 
    printf("OutputRedirect: [%s]\n", (param->outputRedirect != NULL) ? 
    param->outputRedirect: "NULL"); 
    printf ("Background: [%d]\n", param->background); 
    printf ("ArgumentCount: [%d]\n", param->argumentCount); 

    for (i = 0; i < param->argumentCount; i++) 
     printf("ArgumentVector[%2d]: [%s]\n", i, param->argumentVector[i]);  
} 

Param_t* Parse(){ 
    char *toke[MAXARGS]; 
    int i = 0; 
    char str[MAXSTRLENGTH]; 
    int j; 
    int k=0; 

    Param_t* testParam = malloc(sizeof(Param_t)); 
    testParam->argumentCount = 0; 

    printf("Enter your commands:\n"); 
    fgets(str, MAXSTRLENGTH, stdin); 

    toke[i] = strtok(str, " "); 

    //Tokenizes the user input into the toke array 
    while(toke[i] != NULL){ 
     //printf("%s\n", toke[i]); 
     ++i; 
     toke[i] = strtok(NULL, " "); 
    } 

    i=0; 
    char c; 

    while(toke[i] != NULL){ 
     c = toke[i][0]; 
     if(c == '<') 
     { 
      for(j=0; j<strlen(toke[i]); ++j){ 
       toke[i][j] = toke[i][j+1]; 
      } 
      testParam->inputRedirect = toke[i]; 
     } 
     else if(c == '>') 
     { 
      for(j=0; j<strlen(toke[i]); ++j){ 
       toke[i][j] = toke[i][j+1]; 
      } 
      testParam->outputRedirect = toke[i]; 
     } 
     else if(c == '&') 
     { 
      testParam->background = 1; 
      //background 
     } 
     else 
     { 
      testParam->argumentVector[k] = toke[i]; 
      k++; 
      //save as cmd vector 
     } 
     ++i; 
    } 
    testParam->argumentCount = k; 
    return testParam; 
} 
+3

内のすべてのchar *バッファのmainコール自由の終わりに、あなたはより良い助け –

+1

を得るでしょうところでparse.hの内容は何ですか? –

+0

ポインタはちょうど*どこかを指しています*それは指されているデータを保持しません。 – alk

答えて

0

strtok()関数はバッファを作成していないので、あなたがすべてのchar *値を失う理由があります。基本的には、すべてのchar*は、fgets()で読み取る変数strを指すアドレスで構成されています。 str変数は、Parse()関数の最後にしかスコープを持ちません。このため

ソリューション:

置き換えますと

testParam->inputRedirect = toke[i]; 

testParam->inputRedirect = malloc(MAXSTRLENGTH); 
memset(testParam->inputRedirect, 0, MAXSTRLENGTH); 
memcpy(testParam->inputRedirect, toke[i], strlen(toke[i])); 

をしかし、誰free()がないので、これはメモリリークにつながることを、予めご了承ください。

暗示:

main構造の静的インスタンスを作成し、Parse関数へのポインタを与えます。

Parse機能に入力します。あなたは問題を呈する最小サイズにあなたのコードを削減した場合とtestParam

+0

'memset/memcpy'の代わりに' strcpy() 'を使うのはなぜですか? – alk

関連する問題