2016-03-24 10 views
1

私はセグメンテーションフォルトを取得し続けています。realloc()は最初の呼び出しの後に割り当てません

int main(void) 
{ 
    srand(time(NULL)); 

    int cardsSize = 0; //tracks the amount of memory space my pointer is pointing too. 
    int *cards = NULL; 

    if(drawCard(&cards, ++cardsSize) == -1) 
    { 
     printf("Memory allocation failed.\n"); 
     return 0; 
    } 

    if(drawCard(&cards, ++cardsSize) == -1) 
    { 
     printf("Memory allocation failed.\n"); 
     return 0; 
    } 
//... more code 
} 

realloc()が呼び出される部分:

int drawCard(int **cardsptr, int cardsSize) 
{ 
    int newCard = rand() % 13; 

    printf("Address before:\t%p\ncardsSize:\t%d\n", *cardsptr, cardsSize); //an attempt at debugging by examining if the null pointer actually gets an address. 

    *cardsptr = realloc(*cardsptr, cardsSize * sizeof(int)); 

    printf("Address after:\t%p\n", *cardsptr); 

    if(*cardsptr == NULL) 
    return -1; 

    if (newCard > 10) 
    **(cardsptr + cardsSize - 1) = 10; 
    else 
    **(cardsptr + cardsSize - 1) = newCard; 

    printf("Reached.\n"); //to see if I crash before or after trying to assign a value. 
    return 0; 
} 

初めてdrawCard()は、すべてが正常に動作と呼ばれています。 2回目に、新たに割り当てられたメモリに値を割り当てようとするとすぐにセグメンテーションフォールトエラーが発生します。

デバッグメッセージの出力は、次のとおりです。

Address before: (nil) 
cardsSize: 1 
Address after: 0x2428010 
Reached. 

Address before: 0x2428010 
cardsSize: 2 
Address after: 0x2428010 
Segmentation fault (core dumped) 

私の知る限りでは、それが動作するはずです。 drawCard()関数へのポインタNULLへのポインタを渡し、realloc()を呼び出すときに参照を解除します。これによりrealloc()malloc()のようになります。realloc()は、malloc()によって割り当てられたメモリを指すポインタを必要とするため、そのポインタを将来realloc()に渡すことができます。 私はcardsSizeによってサイズを把握し、それをsizeofと組み合わせて使用​​して、適切な量のメモリを再割り当てします。私は、NULLポインタを返したかどうかを確認することによって、realloc()が成功したかどうかをチェックします。 次に、私はそれを2回参照解除するので、私の最初のポインタが今も指しているメモリスポットの1つに値を入れることができます。

+0

'**(cardsptr + cardsSize - 1)='です。繁栄者のために、正直さの良い状態と長い状態は角括弧を使用します。配列はありますか?配列のように使用します。 –

+0

'realloc'が失敗した場合、元のブロックは変更されません。しかし、ポインタは 'realloc'の結果で上書きされ、元のブロックが失われます。これはメモリリークです。また、割り当てたブロックを解放しないでください。ここではスタイルが悪いですが、他の多くのプログラムでは問題があります。小規模なコードで正しく行う習慣を身につけましょう。それで、どこで重要なのでしょうか。 – Olaf

+0

@Olafは、現在必要な場所でrealloc()とfree()を受け取るための一時的なポインタを使用していました。ありがとう。 – RuvenS

答えて

2

問題は**(cardsptr + cardsSize - 1)です。

cards変数へのポインタにcardsSize - 1を追加します。 cardsptrはスタック内の何かを指します。だから、cardsSize - 1を追加すると、あなたは間違いなく間違って参照することができないスタック内の何かに移動し、逆参照するつもりはありません。

*(*cardsptr + cardsSize - 1)以下のいずれかを使用してください。(*cardsptr)[cardsSize - 1]

2

**(cardsptr + cardsSize - 1)は、*(*cardsptr + cardSize - 1)に変更するか、より直感的にする必要があります。(*cardsptr)[cardSize-1]

関連する問題