2011-10-27 7 views
0

私はCの文字列の配列をmallocしています。フリー・オブジェクト・エラー

Assembler(87536) malloc: *** error for object 0x108500840: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

それはなぜです:それを解放した後、私は次のエラーを取得しますか?私はかなりmallocを正しくやっていると確信しています。私はメモリ管理にかなり経験がありますが、なぜこれが私にエラーを与えているのか分かりません。配列にはそれぞれ3文字の文字列を格納する必要があります。文字列の長さはそれぞれ2文字です。ここで

は、私は、配列をmallocingい方法です。ここで

char **reg_store; 
reg_store = malloc(3 * (sizeof(char*))); 
if (reg_store == NULL) { 
    fprintf(Out, "Out of memory\n"); 
    exit(1); 
} 

for (int i = 0; i < 3; i++) { 
    reg_store[i] = malloc(2 * sizeof(char)); 
    if (reg_store[i] == NULL) { 
      fprintf(Out, "Out of memory\n"); 
      exit(1); 
    } 
} 

は、私はそれを解放しています方法です。ここで

for (int i = 0; i < 3; i++) { 
    free(reg_store[i]); 
} 
free(reg_store); 

は、私が間に持っているものです。

// Keeps a reference to which register has been parsed for storage 

int count = 0; 
char *reg = NULL; 
char *inst_ptr // POINTS TO SOME STRING. EXAMPLE: $t2, $t1, $a0 

while (1) { 

    // Parses the string in inst_ptr with dollar, comma and space as a delimiter. 
    reg = parse_token(inst_ptr, " $,\n", &inst_ptr, NULL); 

    if (reg == NULL || *reg == '#') { 
     break; 
    } 

    reg_store[count] = reg; 
    count++; 
    free(reg); 
} 

私はparse_tokenに電話した後、regを印刷していますが、正しく印刷されます。私もreg_store[count]を印刷しており、それも正しく印刷されます。

+0

このコードでは、最も高いメモリデバッグオプションが設定された状態でメモリエラーが発生しません。物事を含めて全体のコードを投稿してください。 – Dani

+0

真ん中にコードを追加しました。これをチェックしてください。ありがとう – darksky

+0

あなたは最初にsizeof(char *)を行いますが、それぞれを実行するとsizeof(char)が呼び出されます。 charはプロジェクトのポインタですか?私が正しいとすれば、最初の呼び出しでは、あなたのシステムのcharのサイズの代わりに、charのポインタのサイズを取得しています(cで再生してからしばらくしています)。 –

答えて

1

あなたの問題はここにある:

reg_store[count] = reg; 
free(reg); 

以降

free(reg_store[i]); 

regが既に解放されて、あなたはそれ別の時間(後でそれを使用して問題の話ではない)解放します。コメントで提案されているように、あなたがその2つのcharatersを知っているので、これは、

strcpy(reg_store[count], reg); 

reg_store[count] = reg; 

を交換または修正するために、それより良いのmemcpyその:

memcpy(reg_store[count], reg, 2); 
+0

それはそれでした!項目を深くコピーする代わりにシャローコピー。ルーキーミス。ありがとうございました! – darksky

+0

そして、strcpy以外のものを使うことを推奨します。これは、バッファオーバーフローの原因となる経路です。私はstrncpyを提案したいが、それはそれ自身のものであるという奇妙な振る舞いをしている。あなたはサイズが2文字であることを知っているので、私はおそらく先に行ってmemcpyを言うと思います。 –

1

mallocedされた直後のすべてのmallocedポインタの値を見るためにprintfsをいくつか追加するか、デバッガを使うことをお勧めします。彼らが解放される直前に同じことをして、彼らが同じであることを確認してください。おそらくメモリ上で踏み込んでいる他の不正なコードがあります。

+0

編集をご覧ください。その間にコードを追加しました。 – darksky

1

あなたの問題はここ特定のコード、「間に」である:

reg_store[count] = reg; 
count++; 
free(reg); 

あなたは、あなたのセットアップ中mallocreg_store[count]を割り当てた後、あなたはregに割り当てられた値を上書きして、reg無料。結果は、元のポインタからのメモリリークがreg_storeであり、すべてをクリーンアップしようとすると各要素のダブルフリーであるreg_storeになります。

reg_store[count]に既に割り当てられているメモリ(もちろんサイズを見てください)にコピーするか、reg_storeの要素に "in between"コードの前にスペースを割り当てないでください。

0

エラーがすでにましたそれをもう一度書く必要はないと指摘した。 しかし、私はあなたがエラーを処理しているように私は好きではないことを指摘することができます。

void freeRegStore(char** reg_store) 
{ 
    int i; 
    if (reg_store != NULL) 
    { 
     for (i = 0; i < 3; i++) 
      free(reg_store[i]); 

     free(reg_store); 
    } 
} 

char** allocRegStore() 
{ 
    int i; 
    char **reg_store; 
    reg_store = calloc(3 * (sizeof(char*)), 1); 
    if (reg_store != NULL) 
    { 
     for (i = 0; i < 3; i++) 
     { 
      reg_store[i] = malloc(2 * sizeof(char)); 
      if (reg_store[i] == NULL) 
      { 
       freeRegStore(reg_store); 
       return NULL; 
      } 
     } 
    } 
    return reg_store; 
} 

このメソッドでは、関数allocRegStoreは、ピースを残さずに十分なメモリがない場合はNULLを返します。 次に、このケースをメインで扱うことができ、割り当て関数自体では処理できません。 私はprintfの使用に同意せず、関数内で終了します。

int main() 
{ 
    char** reg_store = allocRegStore(); 

    if (reg_store == NULL) 
    { 
     puts("Out of memory"); 
     return 1; 
    } 

    ... do your stuff 

    freeRegStore(); 
    return 0; 
} 

このプログラムで使用されているメモリは決してメモリ不足にならないとも言えます。私はそれについて心配しません。

関連する問題