2012-02-26 12 views
0

この問題私はメモリ割り当ての問題のみが不足していると思います。ユーザーが入力したCプログラミングの文字列、ポインタ、および割り当て

(多分一番下までスキップして、いくつかの簡単な提案のための最後の質問を読んで)

私はファイルを読み込み、このプログラムを書いています。ファイルが他のファイルを「含む」場合、それらも読み取られます。別のファイルにファイルが含まれているかどうかを調べるには、文字列の最初の単語を解析します。これを行うために、私は解析された単語を返す関数を書いて、次の単語の最初の文字に設定されたポインタを渡します。たとえば、文字列を考えてみます。

NOTEのファイルは1つのだけ、他のファイルを含めることができ

firstWord ==含める "fooが含まれ"、chPtrは==

fは私のアルゴリズムはfirstWordが文字列の等価性をテストするために解析し、 'include'を指定すると、2番目の単語を解析してファイルの有効性をテストし、ファイルがすでに読み込まれているかどうかを確認します。

私の問題は、多くのファイルが読み込まれており、chPtrが上書きされることです。だから、私は次の単語にポインタを返します。次の単語には、前のファイルの最後の数文字が含まれることがあります。テストファイル-1および偽の名前のサンプルファイルを考えてみましょう:

レッツchPtr元々同じテストファイル-1となりました「偽含める」の解析を考慮してください。

firstWordが含ま==なり、chPtrがに上書きされます抽出bを偽って指す。ですから、chPtrは関数が呼び出されるたびにchPtrが同じメモリアドレスを指しているので、testfile-1の最後の数文字です。これは私の問題です。なぜなら、私が偽を解析するとき、chPtrはlを指しているからです。私の関数のコードは次のとおりです。

char* extract_word(char** chPtr, char* line, char parseChar)  
//POST: word is returned as the first n characters read until parseChar occurs in line 
//  FCTVAL == a ptr to the next word in line 
{ 
    int i = 0; 
    while(line[i] != parseChar && line[i] != '\0')       
    { 
    i++; 
    } 

    char* temp = Malloc(i + 1);   //I have a malloc wrapper to check validity 

    for(int j = 0; j < i; j++) 
    { 
    temp[j] = line[j]; 
    } 
    temp[i+1] = '\0'; 

    *chPtr = (line + i + 1); 
    char* word = Strdup(temp);    //I have a wrapper for strdup too 
    return word; 

私の問題診断は正しいですか?もしそうなら、私はchPtrの深いコピーを作るのですか?また、chPtrの深いコピーを作成するにはどうすればよいですか?

ありがとうございます!

+2

は、なぜあなたは 'STRDUP(TEMP)'とは、その後重複コピーを返すのですか?それ以外の場合は、あなたは 'free(temp)'を決して使用しないので、メモリをリークしてしまいます。実際には 'return temp;'も同様です(新しい割り当てのオーバーヘッドを省きます)。 –

+0

「\ 0」が見つかったときに構文解析を停止しないでください。「これは私の問題です。なぜなら、私は偽を解析すると、chPtrがlを指し示すからです。 –

答えて

0
char* temp = Malloc(i + 1);   //I have a malloc wrapper to check validity 

for(int j = 0; j < i; j++) 
{ 
    temp[j] = line[j]; 
} 
temp[i+1] = '\0'; <------- subscript out of range replace with temp[i] = '\0'; 
+0

ありがとうございます。しかし、私のchPtrがまだ上書きされているので、これは私の問題を解決しません。 – CodeKingPlusPlus

+0

ファイルにchar * chPtrが表示されません。この値は指定したコードで上書きされています。 – Nico

+1

また、文字列がnullターミネータにヒットした場合、バッファ範囲外を指すnextWordを渡すことになり、未定義の動作が導入されます。 – Nico

0

問題がどこにあるかは不明です。しかし、それを見つけるのに役立つツールを使用するかもしれません。

Valgrindはそのような(無料の)ツールの1つです。これは、さまざまなメモリアクセスエラーを検出します。 (それはおそらくあなたのtemp [i + 1] = '\ 0'エラーを見つけられませんでした。なぜならそれは「非常に間違っていません」)。

私たちのCheckPointerツールは別のツールです。 Valgrindはエラーを見つけることができません(たとえば、あなたのバグの割り当てを見つけたはずです)。商用版ではあるが、評価版では小さなサイズのプログラムが処理されるため、うまく動作する可能性があります。 (私は家にいて、限界を覚えていない)。

1

これを正しく理解していれば、ファイルをスキャンする必要があり、 'include'指示文に遭遇した場合、 'include'指示文で指定されたファイルをスキャンし、includeレベル1つのファイルに他のファイルが含まれている可能性があります。

これはそうです(私が間違っている場合は修正してください)。これは古典的な再帰問題です。再帰の利点は、すべての変数がスタック上に作成され、スタックが巻き戻されるときに自然に解放されることです。

のmallocまたは無料か何かのコピーを作成する必要性を必要とせずにこれを行います、次のコード:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define INCLUDE "include" 
#define INCOFFSET 7 

static void 
process_record (char *name, char *buf) 
{ 
    // process record here 
    printf ("%s:%s\n", name, buf); 
} 

// change this to detect your particular include 
static int 
isinclude (char *buf) 
{ 
    //printf ("%s:Record %s INCLUDE=%s INCOFFSET=%d\n", __func__, buf, INCLUDE, 
//  INCOFFSET); 
    if (!strncmp (buf, INCLUDE, INCOFFSET)) 
    { 
     //printf ("%s:Record == include", __func__); 
     return 1; 
    } 
    return 0; 
} 

static int 
read_file (char *name) 
{ 

    //printf ("%s:File %s\n", __func__, name); 
    FILE *fd = fopen (name, "r"); 
    if (!fd) 
    { 
     printf ("%s:Cannot open %s\n", __func__, name); 
     return -1; 
    } 

    char buf[1024]; 
    ssize_t n; 
    while (fgets (buf, sizeof (buf), fd)) 
    { 
     size_t n = strcspn (buf, "\n"); 
     buf[n] = '\0'; 
     //printf ("%s:Buf %s\n", __func__, buf); 
     if (isinclude (buf)) 
     { 
      read_file (buf + (INCOFFSET + 1)); 
     } 
     else 
     { 
      process_record (name, buf); 
     } 
    } 
    fclose (fd); 

    return 0; 
} 

int 
main (int argc, char *argv[]) 
{ 

    int ret = read_file (argv[1]); 
    if (ret < 0) 
    { 
     exit (EXIT_FAILURE); 
    } 
    exit (EXIT_SUCCESS); 

} 
関連する問題