2012-01-30 13 views
5

Qui voglio creare dinamicamente la memoria. qui non conosco le dimensioni dell'output e voglio stampare l'ultimo output finale dopo il ciclo while.Errore di segmentazione in Realloc

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

void main() { 

    char *sdpCommand = "sdptool browse 04:18:0F:B1:48:B5"; 

    FILE *fp; 
    fp = popen(sdpCommand, "r"); 

    char *results = 0; 
    if (fp == NULL) { 
     printf("Failed to run command\n"); 
     return; 
    } 

    char* buffer = malloc(514); 
    while (fgets(buffer, strlen(buffer) - 1, fp) != NULL) { 
     realloc(results, strlen(results) + strlen(buffer)); 
     memcpy(results + strlen(results), buffer, strlen(buffer)); 
    } 
    printf("Output ::: %s", results); 

    /* close */ 
    pclose(fp); 
    sleep(1); 

} 

risposta

11

Ci sono due questioni principali:

  1. realloc()rendimenti il nuovo indirizzo:

    new_results = realloc(results, ...); 
    if (new_results != NULL) { 
        results = new_results; 
    } else { 
        /* handle reallocation failure, `results' is still valid */ 
    } 
    
  2. sizeof() non è il modo giusto per scoprire la dimensione di results e di buffer. Restituirebbe semplicemente la dimensione del puntatore . Per results, probabilmente si desidera tenere traccia delle dimensioni allocate da soli. Per buffer, probabilmente stai cercando strlen().

Una volta a risolvere quanto sopra, è necessario fare in modo che results finisce come una stringa NUL-terminated valido. Questo è necessario per il printf() per funzionare correttamente.

+2

... o 'null' se l'assegnazione non è riuscita. – unwind

+0

Per elaborare, 'sizeof (results)' e 'sizeof (buffer)' restituiscono la dimensione dei puntatori che è effettivamente nota al momento della compilazione. Non c'è modo in C standard di interrogare per la dimensione di un blocco di memoria assegnato dinamicamente. Quindi devi ricordare quanto hai assegnato. –

+0

Per favore, dimmi dove devo cambiare la cosa e il mio codice funziona bene? – user1089679

2

Il tuo codice è solo ciecamente avanti, apparentemente scritto secondo il paradigma "Compila, deve funzionare". Mi dispiace se sembra duro, non è un commento su di te, naturalmente, naturalmente.

È necessario veramente guardare alla documentazione per l'API: s che si sta tentando di utilizzare e analizzare se il proprio utilizzo ha o meno un senso.

Non è possibile ignorare il valore di ritorno da realloc(), come si ottiene la memoria appena assegnata? Non può modificare il puntatore esistente, poiché lo si passa per valore.

Il modo un array dinamico genere deve lavorare di mantenere traccia di tre cose:

  • indirizzo base della matrice corrente
  • Il numero di elementi (byte, nel caso) che l'array detiene al momento
  • il numero di elementi che l'array può contenere, massimo (prima ha bisogno di crescere)

Quando aggiungendo n nuovi elementi, si controlla se così facendo trabocca il numero di elementi, quindi diventa più grande del massimo. Ciò non è consentito, quindi in tal caso è necessario riassegnare l'array di base in modo che i nuovi dati si adattino e (ovviamente) aggiornare di conseguenza lo stato dell'array.

1

realloc (risultati, sizeof (risultati) + sizeof (buffer));

Questa linea potrebbe essere il problema.

  1. realloc() restituisce il nuovo indirizzo assegnato con la dimensione specificata, e non c'è alcuna garanzia che sarà lo stesso indirizzo del puntatore aveva prima; Quindi, è sempre necessario riassegnare il puntatore:

    ptr = realloc (ptr, newSize);

  2. sizeof() non restituirà la dimensione allocata dinamica di un puntatore. In questo caso sizeof(results) e sizeof(buffer) sono probabilmente restituiti sempre 8. È possibile sostituire con:

    results = realloc (risultati, ctr * 514);
    Dove ctr è un short inizializzato con 0 prima del while e conteggio del numero di iterazioni.

  3. Dal buffer è sempre 514 perché non si fa a ridurre il carico redifining a:

    char buffer [514];

    migliori saluti

+0

Assegnare 0 a un puntatore è perfettamente valido e lo standard richiede che il compilatore assegni 'NULL' al puntatore in questi casi. –

+0

Sono stato corretto. Grazie – whitelionV