2016-04-10 10 views
1

私はmallocを使用してmainで作成された3つの配列reallocを作成しようとしていますが、プログラムを実行しようとするたびにエラーが発生し、プログラムが動作しなくなります。文字列配列をRealloc

私の試行では、 "realloc"の後に配列を印刷しようとしましたが、reallocが正常に実行されたように見えますが、新しいレコードをスキャンしてから印刷するとエラーになります。

修正1:提案されているように、scanf行の間違いを訂正しました。最初の新しいレコードが入力されるとすぐにプログラムがエラーになります

すべての入力がわかります!

void addRecord(char** firstName,char** lastName, float* score, int * recordSize) 
{ 
    int add,i; 
    printf("How many records do you want to add? "); 
    scanf("%d", &add); 

    firstName = realloc(firstName, (*recordSize+add)*sizeof(char*)); 
    for (i=*recordSize; i<(*recordSize)+add; i++) 
     firstName[i]= malloc(STRSIZE*sizeof(char)); 

    lastName = realloc(lastName, (*recordSize+add)*sizeof(char*)); 
    for (i=*recordSize; i<(*recordSize)+add; i++) 
     lastName[i]= malloc(STRSIZE*sizeof(char)); 

    score = realloc(score, (*recordSize+add)*sizeof(float)); 
    printf("Please enter the record to be added: \n"); 
    printf("FirstName LastName Score\n"); 

    for (i=*recordSize; i<*recordSize+add; i++) 
     scanf("%s %s %f", firstName[i], lastName[i], &score[i]); 
    *recordSize +=add; 
} 
+1

'scanf()'の '%s'フォーマット指定は' char * '、あなたは 'char ** 'を提供しています。 'firstName [i]'は 'char *'ですので、 '&'演算子を使う必要はありません。 –

+0

[mcve]は常に投稿してください。 –

答えて

0

ポインタアドレスが変更された場合、再割り当てがメイン関数に表示されないことに注意してください。文字列の配列全体を再割り当てしていますが、この変更はaddRecord()関数でのみ発生します。主な機能に戻るときは、が新しいメモリアドレスを返して元のメモリブロックを解放できるので、dangling pointerがあるかもしれません。それはがaddRecord()の別のものを印刷し、あなたの主な機能がaddRecord()の後に印刷することができます。例えば

:文字列の配列のために

#include <stdio.h> 

/* Simulate the reallocation of bar by swapping oldbar and bar. */ 
void foo(int *bar) 
{ 
    static int *oldbar = NULL; 

    if (oldbar == NULL) { 
     oldbar = bar; 
     bar = NULL; 
    } else { 
     bar = oldbar; 
     oldbar = NULL; 
    } 

    printf("bar after reallocating is: %p\n", (void *)bar); 
} 

/* Notice the extra * below and the dereferencing of the pointer, allowing 
    main() to see the change. */ 
void foo_works(int **bar) 
{ 
    static int *oldbar = NULL; 

    if (oldbar == NULL) { 
     oldbar = *bar; 
     *bar = NULL; 
    } else { 
     *bar = oldbar; 
     oldbar = NULL; 
    } 

    printf("bar after reallocating is: %p\n", (void *)bar); 
} 

int main(void) 
{ 
    int bar[] = {1, 1, 2, 3, 5, 8}; 
    int *barptr = bar; 

    printf("barptr before reallocating is: %p\n", (void *)barptr); 
    foo(barptr); 
    printf("barptr after reallocating is: %p\n\n", (void *)barptr); 

    printf("barptr before reallocating is: %p\n", (void *)barptr); 
    foo_works(&barptr); 
    printf("barptr after reallocating is: %p\n", (void *)barptr); 
} 

、あなたはちょうど私がfoo_works()の定義に行ったように、パラメータおよび間接参照に別の*を追加する必要があります。こうすることで、配列へのポインタが得られます。このポインタを使用すると、メイン関数に変更が表示されます。もちろん、これはあなたがThree Star Programmerになることを意味します。代わりに、あなたのレコードに構造体を使用するようにリファクタリングすることが考えられます。

+0

ありがとう!三つ星のプログラミング作品!! 構造が私の頭にあった最初のものでした。残念なことに、宿題には構造を使用する必要がありません。 –

1
scanf("%s %s %f", firstName[i], lastName[i], &score[i]); 

あなたのメモリへのポインタへのポインタを使用していました。 '&'を削除し、メモリへのポインタをscanf()に送信してください。

+0

最後の引数は '&score [i]'ではありませんか? – stackptr

+0

@stackptrはい、そうです。私は編集します。いい視点ね。 – Logicrat

+0

私は同意し、修正されました。しかし、それは完全に問題を解決しませんでした。 –