2016-04-10 45 views
1

Bir işlev yazmaya çalışıyorum 3 ana dizisi malloc kullanılarak oluşturuldu, ancak programı çalıştırmaya çalıştığımda her zaman bir hata alıyorum ve program çalışmayı durdurur.Bir dize dizisi Realloc

Hata ayıklama girişimlerimde "realloc" dan sonra dizileri yazdırmaya çalıştım ve realloc başarıyla yapıldı gibi görünüyor, ancak bu yeni kayıtlara taradıktan sonra, yazdırmak için, hata alıyorum.

DÜZELTME 1: Scanf satırındaki hatayı önerilen şekilde düzeltildi. Program, ilk yeni kayıt

girişine girer girmez hata yapar. Herhangi bir girdi takdir edilir!

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() 'için'% s' biçim belirtimi 'char *' bekler, ama sen char '' sağlıyorsun. 'firstName [i]' 'char *' zaten, bu yüzden '&' operatörünü kullanmanız gerekmiyor. –

+0

Her zaman bir [mcve] göndermelisiniz. –

cevap

0

İşaretçi adresi değiştiğinde yeniden paylaşımlarınızın ana işlevinizde görünmeyeceğini bilmelisiniz. Tüm dizi dizisini yeniden ayırıyorsunuz, ancak bu değişiklik yalnızca addRecord() işlevinizde gerçekleşiyor. Ana işlevinize geri döndüğünüzde, realloc(), realloc() yeni bir bellek adresi döndürebilir ve orijinal bellek bloğunu boşaltabileceğinden, dangling pointer olabilir. Bu printf("%p\n", firstName);addRecord() içinde farklı şeyler yazdırabilir ve addRecord() döndükten sonra ana işlevinizi döndürür. Örneğin

: dize dizisi için

#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); 
} 

, sadece ben foo_works() tanımında olduğu gibi parametre ve dereference başka * eklemeniz gerekir. Bu şekilde, dizinin ana işlevinize görünür olmasını sağlayan bir işaretçiniz vardır. Tabii ki, bu, bir Three Star Programmer olacağınız anlamına gelir ve kayıtlarınız için yapıları kullanmak için yeniden yapılandırmayı düşünebilirsiniz ...

+0

Teşekkürler! Üç Yıldız programlama çalışıyor! Yapılar, aklıma gelen ilk şeydi. Maalesef, ev ödevi, hiçbir yapının kullanılmamasını gerektirir. –

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

Eğer bellek için bir işaretçi bir işaretçi kullanıyorlardı. '&' düğmesini bırakın ve belleğinize bir işaretçi gönderin scanf().

+0

Son argümün, '& score [i] 'olması gerekmiyor mu? – stackptr

+0

@stackptr Evet, öyle. Ben düzenleyeceğim İyi bir nokta. – Logicrat

+0

Kabul ediyorum ve düzeltildi. Ama bu sorunu tamamen düzeltmedi. –

İlgili konular