Newsgroup: it.comp.lang.c
Titolo: Presentazione e qualche quesito

Salve a tutti, sono alle prime armi con il linguaggio C e ho ancora
qualche problemino a capire alcuni concetti.
Sto scrivendo un programma per trovare le radici primitive di un
numero primo grande e negli ultimi test sto avendo delle
segmentation fault quando tento di chiudere un file. Almeno questo è
il risultato che viene dato dal debugger di eclipse :)
La cosa strana è che isolando la funzione che credo sia causa del
problema e creando un main apposito non riesco a
riprodurre l'errore.
Il codice d'esempio l'ho postato qui: 
http://pastie.org/840940
giusto per non sporcare troppo il ng.
Nel programma originale ci sono un paio di funzioni in più che hanno
come scopo quello di automatizzare alcune funzioni come la generazione
dei primi che mi servono, cambiare il nome del file se trovano una
copia (tipo una rotazione di log) e creare il file da cui prendere i
numeri (il filelista32 che si legge nel codice).
Vi sono grato in anticipo per ogni aiuto, sto impazzendo dietro al
programma :)
Ciao a presto
Pierpaolo

 writes:

Magari ci vorrebbe qualche errore più dettagliato, tipo lanciandolo da
shell...
Comunque 
--8<---------------cut here---------------start------------->8---
char *reading;
reading = malloc(sizeof(int));
--8<---------------cut here---------------end--------------->8---
Ad esempio questo non ha senso perché
1. reading è una variabile locale non usare malloc
2. prima la dichiari char * e poi gli dai come dimensione quella di int.
Ti basta un "char reading".
Poi magari indenta meglio e di più (almeno 4 spazi) e metti qualche
spazio tra le virgole, così diventa più leggibile..

 wrote:

Ciao, grazie per la risposta.
reading sarebbe una stringa, mi pare di dover allocare lo spazio per
una stringa, o se la metto come locale non ne ho bisogno?
Posso postare il codice prodotto dalla shell con -Wall e -pedantic:
/
*--------------------------------------------------------------------------------------------------------------------------------
*/
**** Clean-only build of configuration Debug for project genfinder
****
make clean
rm -rf  ./listaprova.o  ./listaprova.d  genfinder
**** Build of configuration Debug for project genfinder ****
make all
Building file: ../prova.c
Invoking: GCC C Compiler
gcc -I/home/melkor/libs/C/miracl -O0 -g3 -pedantic -Wall -c -fmessage-
length=0 -MMD -MP -MF"prova.d" -MT"prova.d" -o"prova.o" "../prova.c"
../prova.c: In function ‘readffactor’:
../prova.c:260: warning: ISO C90 forbids variable length array
‘current’
../prova.c:284: warning: function returns address of local variable
../prova.c: In function ‘prootsfind’:
../prova.c:294: warning: ISO C90 forbids variable length array
‘factordivphi’
../prova.c: In function ‘main’:
../prova.c:325: warning: ISO C90 forbids mixed declarations and code
../prova.c:329: warning: unused variable ‘fileg’
../prova.c:327: warning: unused variable ‘out2’
Finished building: ../prova.c
Building target: genfinder
Invoking: GCC C Linker
gcc -L/home/melkor/libs/C/miracl -o"genfinder"  ./prova.o   -lmiracl
Finished building target: genfinder
/
*--------------------------------------------------------------------------------------------------------------------------------
*/
Questo è l'output completo del programma che mi da errore di cui ho
postato prima il "toy example". Ieri dopo un pò di prove ho notato
che l'errore capita dalla seconda esecuzione consecutiva in poi.


Dunque questo è male:
../prova.c:284: warning: function returns address of local variable
Vuol dire che ritorni fuori da una funzione qualcosa non allocato con
malloc ma come variabile automatica, sicuramente avrai qualche problema.
Inoltre giusto, reading è una stringa, quindi di sicuro non la allochi
come 1 intero, ma se mai come N char.
Tipo
char reading[50] (visto che il limite mi sembra quello).
Poi magari fai in modo di non ottenere più warnings...

 Poi magari fai in modo di non ottenere più warnings...
Tenterò :)
Pierpaolo
I

 allocato grande in modo da farci stare comunque molti char?
Ehm guarda che il 50 l'ho preso dal tuo codice..
Se con fgets prendi 50 char alla volta che senso ha allocarne di più o
(peggio) di meno?
PS. non incollare tutto quando rispondi ma cancella ciò che non serve

Le due cose che ha gia' detto Andrea devono essere messe a posto 
assolutamente, e sono entrambe legate alla gestione della memoria:
1. a reading viene allocato lo spazio di un int, e ci metti una stringa? 
Quello sara' un buffer overflow sicuro
2. current e' un array allocato automaticamente sullo stack, che verra' 
distrutto all'uscita dalla funzione: non puoi restituirlo (quel puntatore 
punbta a della memoria che non esiste piu')
Per la 2. devi allocare l'array dinamicamente nello heap:
big* current = malloc(linenumb * sizeof(*current));
A questo punto puoi si' restituire current alla fine, come puntatore ad un 
array di big:
return current;
Pleg

Ciao, scusate se non ho risposto subito, ma ho avuto qualche problema
a rattoppare il tutto :)
Alla fine ho risolto eliminando l'array che usavo per passare i dati
che mi servivano e creando una lista
dei big che mi servivano. Ho sostituito tutte le "allocazioni
dinamiche" di stringhe (che avevo visto sul libro.. mah :D)
Con delle allocazioni "statiche" e tutto funziona a meraviglia.
Mi sono aiutato un pò con Valgrind che ha trovato qualche memory leak
qui e lì :\
Vi ringrazio per il supporto :)
Ciao
Pierpaolo

 writes:

In generale non è che le allocazioni dinamiche siano il male, sono
spesso necessarie e l'importante è hc 

Scusate qualche problema con il client...
In generale non è che le allocazioni dinamiche siano il male, sono
spesso necessarie e l'importante è che liberi la memoria una volta che
hai finito di lavorarci.
Per delle stringhe "immutabili" in effetti non vedo che senso abbia, ma
il libro avrà avuto le sue ragioni per consigliarlo...


Nel senso, ad ogni malloc far corrispondere la free?
Si cerco di farlo, il problema è stato che il codice era molto sporco
per via
di una progettazione in corso d'opera. Mi serviva riprendere un pò in
mano il
linguaggio e ricordarmi un pò come funzionava. Oltretutto poichè il
problema
del programma è tutt'altro che semplice il codice si è sporcato oltre
ogni modo.
Infatti ha aiutato molto riscriverlo confrontando e pulendo.
Per l'allocazione dinamica di stringhe è corretto fare una
dichiarazione ad un puntatore di char
e allocare la dimensione a int, o è meglio dargli un'allocazione al
puntatore stesso?

 puntatore stesso?
Non capisco cosa vuoi dire. Ma di certo non ha senso allocare lo spazio 
per tenere il puntatore alla stringa.
E.