2012-02-26 9 views
1

2つの(できれば素早く)質問があります。私はデータのためのスペースを節約するためにmallocを使用していますが、reallocは問題を引き起こしていると思います。以下のコードでは、私は8文字のポインタの配列を持っている - それを埋める必要があります - 私は別の 8文字のポインタを(そして別の8、など)を持つように拡張しようとしています。 reallocのは(すなわち、それは一度、配列を拡張します)このを最初に行いますが、その後、私は次のエラーを取得する:C-malloc、realloc、freeで適切なメモリ処理を学ぼうとしています

*** glibc detected *** ./a.out: realloc(): invalid next size: 

私の知る限り、何も変更されません。なぜreallocは8の配列で動作しますが、16の配列では動作しませんでしたか?

私の2番目の質問はメモリリークです。私はまだプログラムで自由にする必要があることについてはまだ分かりません。私はinputcpyを解放する必要があることを他の人に知らされています。それはすべてここにありますか?また、プログラムのどの時点で私はそれを解放したいですか?

#define DEBUG 1 

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

char ** getArgs(char *input, char **args, int ct); 
char ** args; 

int main(int argc, char* argv[]) { 
    char input[]="echo arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13"; 
    char inputcpy[strlen(input)]; 
    strcpy(inputcpy, input); 
    char * prog=strtok(input, " "); 

    /*Saving space for an array of 8 strings*/ 
    args=(char **) calloc(8, sizeof(char *)); 

    getArgs(inputcpy, args, 1); 

    if(DEBUG) { 
    printf("arg address after: %p\n", args); 
    } 

    int q; 
    int pid=fork(); 
    if (pid==0) { 
    execvp(prog, args); 
    return 0; 
    } 
    else { 
    int status=0; 
    wait(&status); 
    } 
} 

char ** getArgs(char *input, char **args, int ct) { 
    int adj=(ct-1)*8;//if we recurse, this ensures correct indexes are used 
    char *inputcpy=malloc(strlen(input)); 
    strcpy(inputcpy, input); 

    /*Initialize indexes/Prepare for copying*/ 
    int i; 
    if(ct==1) { 
    i=1; 
    args[0]=" "; //quick hack to ensure all args are used by exec() 
    } 
    else 
    i=0; 

    /**Actually do the copying now**/ 
    char *temp=strtok(NULL, " "); 
    args[adj+i++]=temp; 
    while (temp != NULL && i<8) { 
    temp=strtok(NULL, " "); 
    args[adj+i++]=temp; 
    } 

    /*If there are more args than we have room for*/ 
    if(i>=8){ 
    /*Increase the array to store 8 more strings*/ 
    args= (char **) realloc(args, sizeof(args)+8*sizeof(char *)); 
    getArgs(inputcpy, args, (++ct)); 
    } 

    return NULL; 
} 
+1

これは多くのコードを見ているので、私は気づいてまとめません。もしあなたが '新しい'何か、それを '削除'します。あなたが 'malloc'何かを'自由にする 'こと。 'sizeof'は' args'(ポインタ)のサイズを返します。ポインターはポインタではなく、あなたのバグです。 –

+0

'char * inputcpy = malloc(strlen(input));'はヌル文字を考慮する必要があるので 'char * inputcpy = malloc(strlen(input)+ 1);'にする必要があります。 –

答えて

2
char *inputcpy=malloc(strlen(input)); 
strcpy(inputcpy, input); 

あなたの文字列のための十分なスペースを割り当てていない、次のようになります。malloc(strlen(input) + 1);

同じここ

char inputcpy[strlen(input)]; 
strcpy(inputcpy, input); 

文字列がnullを含む終わる文字の並びで、文字列の長さはヌル文字に先行する文字数です。

また、あなたは間違ってreallocを使用している:

args= (char **) realloc(args, sizeof(args)+8*sizeof(char *)); 

を、この使用中のメモリリークの可能性があります。

freeについては、あなたがすべきことは簡単です:すべてmallocには対応するfreeが必要です。

+0

あなたの応答とヌル文字のためのスペースの不足を指摘してくれてありがとう - 固定!私はあなたの 'realloc'コメントについて質問があります。 reallocが既にargsを再割り当てしている場合、どうすれば前のargsを解放できますか? 'var = realloc(var、size)'を使うのは悪い習慣ですか? – user1209326

+0

@ user1209326はい、 'realloc'が' NULL'を返すと、 'args'を上書きして元の' args'を 'フリーにする '方法がないかもしれないからです。あなたのコードでは、あなたのプログラムをランダムな問題にさらすライブラリ関数の戻り値をチェックしません。 – ouah

0

私はあなたの最後の質問に答えます: また、プログラムのどの時点でそれを解放したいですか?

まあ、mallocと呼ばれる関数の復帰前に解放することをお勧めします。あなたがそうするなら、後でメモリリークが心配する必要はありません。

しかし、getArgs()関数が終了したときに、あなたのケースのmain関数の呼び出し関数はfree()を呼び出して、mainに制御を返します。これは、free()で別のポインタ変数を使用しても問題ありません。新しいポインタに同じアドレスが格納されていることを確認するだけです。

関連する問題