Domanda

Orso con me. Non ho scritto in C in 8 anni e sono totalmente sconcertato perché il mio manipolazione di stringhe non funziona. Sto scrivendo un programma che loop per sempre. Nel loop inizializzo due puntatori char ciascuno è passati ad una funzione che aggiungere testo al puntatore char (array). Quando le funzioni sono fatto stampo il puntatore char e liberare i due puntatori char. Tuttavia gli stampi programma dopo 7 iterazioni con il seguente messaggio di errore

  

* glibc rilevato * ./test: doppio libero o corruzione (fasttop): 0x0804a168 ***

#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include string.h
#include stdio.h
#include stdlib.h
#include errno.h
#include time.h

char *SEPERATOR = "|";

void getEvent (char* results);
void getTimeStamp(char* timeStamp, int timeStampSize);
void stringAppend(char* str1, char* str2);

int main (int argc, char *argv[])
{
  int i = 0; 
  while(1)
  { 
    i++;
    printf("%i", i);    

    char* events= realloc(NULL, 1); 
    events[0] = '\0';
    getEvent(events);

    char* timestamp= realloc(NULL, 20);
    timestamp[0] = '\0';
    getTimeStamp(timestamp, 20);

    printf("%s", events);
    printf("timestamp: %s\n", timestamp);

    free(events);
    free(timestamp);
  } 
}

void getEvent (char* results)
{
  stringAppend(results, "a111111111111");
  stringAppend(results, "b2222222222222");
}

void getTimeStamp(char* timeStamp, int timeStampSize)
{
  struct tm *ptr;
  time_t lt;
  lt = time(NULL);
  ptr = localtime(&lt);
  int r = strftime(timeStamp, timeStampSize, "%Y-%m-%d %H:%M:%S", ptr);
}

void stringAppend(char* str1, char* str2)
{   
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1;
  printf("--%i--",arrayLength);

  str1 = realloc(str1, arrayLength);
  if (str1 != NULL)
  {
    strcat(str1, SEPERATOR);
    strcat(str1, str2);
  }
  else
  {
    printf("UNABLE TO ALLOCATE MEMORY\n");
  }
}
È stato utile?

Soluzione

Il problema è che, mentre stringAppend rialloca i puntatori, solo stringAppend è a conoscenza di questo fatto. È necessario modificare stringAppend a prendere puntatore-a-puntatori (char **) in modo che i puntatori originali vengono aggiornate.

Altri suggerimenti

Si sta riallocando str1 ma non passando il valore fuori della funzione, in modo che il puntatore potenzialmente cambiato è trapelato, e il vecchio valore, che è stato liberato da realloc, viene liberato di nuovo da voi. Questo fa sì che l'avviso "doppio libero".

Questa linea in stringAppend:

str1 = realloc(str1, arrayLength);

cambia il valore di una variabile locale in stringAppend. Questo locale variabile denominata str1 ora punta o nella memoria riassegnazione o NULL.

Nel frattempo variabili locali in getEvent mantengono i valori che avevano prima, che ora di solito puntano a memoria liberata.

Tutti i commenti dove molto disponibile. Naturalmente ha senso totale perché l'errore stava accadendo. Ho finito per risolverlo effettuando le seguenti modifiche.

Per entrambi il getEvent e stringAppend torno il puntatore char.

per es.

char* stringAppend(char* str1, char* str2) 
{    
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1; 
  printf("--%i--",arrayLength); 

  str1 = realloc(str1, arrayLength); 
  if (str1 != NULL) 
  { 
    strcat(str1, SEPERATOR); 
    strcat(str1, str2); 
  } 
  else 
  { 
    printf("UNABLE TO ALLOCATE MEMORY\n"); 
  } 
  return str1;
} 

Questa non è una risposta alla tua domanda (e non avete bisogno di uno, dal momento che l'errore è stato fatto notare), ma ho alcuni altri commenti circa il vostro codice:

char* events= realloc(NULL, 1); 
events[0] = '\0';

Non c'è prova che realloc memoria allocata con successo.

char* timestamp= realloc(NULL, 20);
timestamp[0] = '\0';

Lo stesso problema qui. In questo caso, non è necessario realloc a tutti. Poiché si tratta di un buffer di dimensione fissa, è possibile utilizzare solo:

char timestamp[20] = "";

E non fare questo:

str1 = realloc(str1, arrayLength);

, perché se realloc non riesce, ti orfano la memoria che str1 stava indicando prima. Invece:

char* temp = realloc(str1, arrayLength);
if (temp != NULL)
{
    str1 = temp;
    ...
}

Si noti che dal momento che si sta modificando stringAppend per restituire la nuova stringa, si dovrebbe fare controlli simili nelle funzioni di chiamata.

Inoltre, "separatore" si scrive con due A, non con due Es.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top