2016-11-06 11 views
0

なぜfree_memory関数内でセグメンテーションフォルトが発生しているのかわかりません。ここではプログラムは次のとおりです。Cでメモリを解放しているときにこのエラーを理解できません

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

void allocate_memory (char **cells) 
{ 
    int i; 

    cells = (char **) malloc(9 * sizeof(char *)); 
    if (cells == NULL) 
    { 
     perror("Couldn't allocate memory"); 
     exit(1); 
    } 

    for (i = 0; i < 9; i++) 
    { 
     cells[i] = (char *) malloc(9 * sizeof(char)); 
     if (cells[i] == NULL) 
     { 
      perror("Couldn't allocate memory"); 
      exit(1); 
     } 

     memset(cells[i], 1, 9); 
    } 
} 

void free_memory (char **cells) 
{ 
    int i; 

    for (i = 0; i < 9; i++) 
    { 
     free(cells[i]); 
    } 

    free(cells); 
} 

int main (int argc, char *argv[]) 
{ 
    char **cells = NULL; 

    allocate_memory(cells); 
    printf("Allocated\n"); 
    free_memory(cells); 

    return 0; 
} 

デバッガは、エラーについては、このメッセージを表示します。

Process 1433 launched: '/Users/Jaime/Documents/workspaceC/PruebasC/PruebasC/sk' (x86_64) 
Allocated 
Process 1433 stopped 
* thread #1: tid = 0x1058a, 0x0000000100000e95 sk`free_memory + 37, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) 
    frame #0: 0x0000000100000e95 sk`free_memory + 37 
sk`free_memory: 
-> 0x100000e95 <+37>: movq (%rcx,%rax,8), %rdi 
    0x100000e99 <+41>: callq 0x100000f20    ; symbol stub for: free 
    0x100000e9e <+46>: movl -0xc(%rbp), %eax 
    0x100000ea1 <+49>: addl $0x1, %eax 

私は誰も私を助けることを願って、私が悪いのポインタをアクセスしていますが、なぜ、私は得ることはありません。

+0

[関数fgets()を使用して標準入力からの読み込み]の可能性のある重複します(http: //stackoverflow.com/questions/40412010/reading-from-stdin-using-fgets) –

答えて

1

によって設定されていなかったかのように

外部効果があります。あなたはコピーを変更しています。

、関数内のポインタを変更したい場合は、関数へのポインタへのポインタを渡す必要があります:

... 

void allocate_memory (char ***cells) 
{ 
    int i; 

    *cells = (char **) malloc(9 * sizeof(char *)); 
    if (*cells == NULL) 
    { 
     perror("Couldn't allocate memory"); 
     exit(1); 
    } 

    for (i = 0; i < 9; i++) 
    { 
     (*cells)[i] = (char *) malloc(9 * sizeof(char)); 
     if ((*cells)[i] == NULL) 
     { 
      perror("Couldn't allocate memory"); 
      exit(1); 
     } 

     memset((*cells)[i], 1, 9); 
    } 
} 

...  

int main (int argc, char *argv[]) 
{ 
    char **cells = NULL; 

    allocate_memory(&cells); 

    ... 
} 
+0

ありがとう!本当に素敵な答えの男:D –

0

Cは、引数引き渡しに値渡しを使用します。場合にはあなたがcellsに自分自身をメモリを割り当てたい、あなたはどちらか

  • は、それへのポインタを渡す必要がある、または
  • リターン新たに割り当てられたポインタをしてmain()に戻っcellsに保管してください。

    機能のcellsは、その機能から復帰するとcellsに加えられた変更がすべて失われてしまうという点でローカルです。その結果、

cellsがすべてで、任意の有効なメモリを指し示していないとして、free_memory()関数内で、アクセスcells[i]は、無効です。無効なメモリにアクセスしようとすると、undefined behaviorが呼び出されます。

0

割り当て関数は、新しく割り当てられたブロックを返しません。 allocate_memory(cells);細胞は、あなたがあなたのmaincellsallocate_memory内の変更されていません(以前にNULLに設定)機能

関連する問題