2009-07-15 10 views
5

Il mio programma è come questo (main.c):Malloc, puntatori di stringa, e Valgrind

#include <stdlib.h> 
#include <stdio.h> 
void main(){ 
    char *first="hello "; 
    char *second="world!"; 
    char *seq=(char *)malloc((strlen(first)+1)*sizeof(char)); 
    strcat(strcpy(seq,first),second); 
    printf("%s\n",seq); 
    free(seq); 
} 

e il debug con lo strumento valgrind, ha detto che ($: valgrind --tool = memcheck --leak-check = pieno --track-origini = yes ./main):

==5118== Memcheck, a memory error detector. 
==5118== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al. 
==5118== Using LibVEX rev 1884, a library for dynamic binary translation. 
==5118== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP. 
==5118== Using valgrind-3.4.1, a dynamic binary instrumentation framework. 
==5118== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al. 
==5118== For more details, rerun with: -v 
==5118== 
==5118== Invalid write of size 1 
==5118== at 0x402575B: strcat (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x80484EB: main (main.c:7) 
==5118== Address 0x418a02f is 0 bytes after a block of size 7 alloc'd 
==5118== at 0x402522D: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x80484C3: main (main.c:6) 
==5118== 
==5118== Invalid write of size 1 
==5118== at 0x4025777: strcat (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x80484EB: main (main.c:7) 
==5118== Address 0x418a034 is 5 bytes after a block of size 7 alloc'd 
==5118== at 0x402522D: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x80484C3: main (main.c:6) 
==5118== 
==5118== Invalid read of size 1 
==5118== at 0x4025963: strlen (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x40A0FA4: puts (in /lib/libc-2.10.1.so) 
==5118== by 0x80484F7: main (main.c:8) 
==5118== Address 0x418a02f is 0 bytes after a block of size 7 alloc'd 
==5118== at 0x402522D: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x80484C3: main (main.c:6) 
==5118== 
==5118== Invalid read of size 1 
==5118== at 0x40ACEFE: _IO_default_xsputn (in /lib/libc-2.10.1.so) 
==5118== by 0x40AA3D0: [email protected]@GLIBC_2.1 (in /lib/libc-2.10.1.so) 
==5118== by 0x40A1020: puts (in /lib/libc-2.10.1.so) 
==5118== by 0x80484F7: main (main.c:8) 
==5118== Address 0x418a02f is 0 bytes after a block of size 7 alloc'd 
==5118== at 0x402522D: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x80484C3: main (main.c:6) 
hello world! 
==5118== 
==5118== ERROR SUMMARY: 17 errors from 4 contexts (suppressed: 13 from 1) 
==5118== malloc/free: in use at exit: 7 bytes in 1 blocks. 
==5118== malloc/free: 1 allocs, 0 frees, 7 bytes allocated. 
==5118== For counts of detected errors, rerun with: -v 
==5118== searching for pointers to 1 not-freed blocks. 
==5118== checked 47,492 bytes. 
==5118== 
==5118== 
==5118== 7 bytes in 1 blocks are definitely lost in loss record 1 of 1 
==5118== at 0x402522D: malloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) 
==5118== by 0x80484C3: main (main.c:6) 
==5118== 
==5118== LEAK SUMMARY: 
==5118== definitely lost: 7 bytes in 1 blocks. 
==5118==  possibly lost: 0 bytes in 0 blocks. 
==5118== still reachable: 0 bytes in 0 blocks. 
==5118==   suppressed: 0 bytes in 0 blocks. 

Chi mi può dire perché e come rimediare.

risposta

17
char *seq=(char *)malloc((strlen(first)+1)*sizeof(char)); 

Si sta allocando memoria per una stringa delle dimensioni di appena 'prima'.

strcat(strcpy(seq,first),second); 

E quindi si prova ad adattare sia il primo che il secondo. Non funzionerà mai. strcat non crea più memoria, è necessario averlo incluso nello malloc.

There is no need to cast the result of malloc in pure C.

Inoltre non è necessario fare sizeof(char), come che è garantito per essere 1. Alcuni piace avere lì comunque essere explict sul tipo nel caso in cui cambia, alcuni lo considerano disordine.

+1

non è necessario eseguire il cast del valore di ritorno di 'malloc()' in C; inoltre, 'sizeof (char)' è sempre '1' – Christoph

2

Si assegna solo uno spazio sufficiente per primo in seq.

1

seq è solo (strlen (first) +1) * sizeof (char) long, non abbastanza per contenere la stringa concatenata prima + secondo.

-1

ho potuto vedere che la linea:

strcat (strcpy (seq, prima), secondo);

non è incorniciato in modo errato. Il motivo è che stai facendo una concatenazione di stringhe, in cui non stai dando una fonte adeguata. Funzionerà bene, se si segrega la sintassi sopra in 2 righe.

strcpy (seq, prima); strcat (seq, secondo);

Questo perché, quando si esegue una copia di stringa, verrà copiata la stringa da "primo" a "seq". Ora, per la concatenazione di stringhe, dal momento che non è stato possibile trovare la fonte corretta [ricorda che non hai specificato specificamente che la fonte è "seq"], sta dando un problema di perdita di memoria di scrittura non valido.

Spero che questo chiarisca la tua domanda. Si prega di annullare, se sono necessarie ulteriori informazioni, per lo stesso.

+0

Inoltre, come detto sopra, da altri, è necessario allocare la memoria appropriata per seq, da memorizzare anche per" second ". –

+0

'strcpy()' restituisce il suo primo argomento, quindi 'strcat (strcpy (seq, first), scond)' è equivalente a 'strcpy (seq, fiest); strcat (seq, secondo); '. –

3

Dov'è il corrispondente free() per il malloc()?

+0

haha, l'ho perso, voglio solo dimostrare l'errore di strcpy e strcat. Naturalmente, dovrei aggiungere gratuitamente (seq); grazie lo stesso –

+0

la memoria è implicitamente liberata dal sistema operativo dopo 'main()' restituisce – Christoph

+1

Wow - perché mai mi prendo fastidio chiamare 'free()' allora?:-) – Justicle