|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 3609
|
[C] Problema di segmentation fault durante l'esecuzione
Ciao a tutti, ho fatto un semplice programmino il quale legge una per una le righe di un file, vede se c'è la stessa riga nel secondo file, se non c'è la inserisce in un terzo file vuoto.
Insomma in pratica fa file1 - file2 = file3 Solo che ho un piccolo problema con la memoria, cioè che il file1 non lo posso fare più di 507 righe... Se lo faccio più grande mi dà errore dopo appunto 507 righe restituendomi: if ((stream2 = fopen(da_togliere, "rt")) == NULL) printf("....."); cioè io cambio di dimensioni il file1 e mi dà errore al file2... eccovi il codice: Codice:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_BUF 15
int main()
{
char *unique= "Unique.txt";
char *da_togliere= "da togliere.txt";
char *buoni= "buoni.txt";
char *c= (char *) malloc((MAX_BUF * sizeof(char *)) + 1);
char *c2= (char *) malloc((MAX_BUF * sizeof(char *)) + 1);
/* dichiara lo stream e il prototipo della funzione fopen */
FILE *stream1, *stream2, *stream3, *fopen();
/* apre lo stream del file */
stream1 = fopen(unique, "rt");
stream3 = fopen(buoni, "wt");
// apro i files
if ((stream1 = fopen(unique, "rt")) == NULL)
printf("Non posso aprire il file %s\n", unique);
if ((stream3 = fopen(buoni, "wt")) == NULL)
printf("Non posso aprire il file %s\n", buoni);
// comincio la scansione dall'inizio del file "da_togliere"
while (!feof(stream1)){
int i= 1;
// if (!fgets(c, 3, stream1)) printf("");
fgets(c, 100, stream1);
// apro il file "unique"
stream2 = fopen(da_togliere, "rt");
if ((stream2 = fopen(da_togliere, "rt")) == NULL)
printf("Non posso aprire il file %s\n", da_togliere);
while (!feof(stream2)){
fgets(c2, 100, stream2);
if (strcmp(c, c2) == 0) {
i=0;
break;
}
}
if (i==1){
fputs(c, stream3);
printf("%s", c); //per vedere a video quello che fa
}
}
fflush(stream1);
fclose(stream1);
fflush(stream2);
fclose(stream2);
fflush(stream3);
fclose(stream3);
}
anche se metto fgets(c2, 100000, stream2); è sempre lo stesso...
__________________
Notebook MSI GT73VR 7RE TITAN SLI: 17.3" 4K IPS @ 120 Hz, i7-7820HK, 2x Nvidia GeForce GTX 1070 (SLI) - 8 GB GDDR5, 2x 16GB DDR4 2.400Mhz, Super Raid 4-512GB NVMe SSD +1TB (SATA) 7200rpm In vendita: |Utenti consigliati|: Marcondiron99 |Utenti sconsigliati|: iltoffa, otherman |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Mar 2007
Città: Milano Beach
Messaggi: 1696
|
1: Come fa a darti segfault in fase di compilazione?
2: Dichiari c2 come array contenente 16 char e poi fai fgets di 100? 3: perchè dichiari "char * fopen()"? fopen() è funzione contenuta nella stdlib, ti basta includere stdlib.h
__________________
~ Cthulhu: MacBookPro 13.3" ~ Azathoth: D510MO Ultima modifica di GByTe87 : 09-12-2011 alle 19:22. |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 3609
|
Quote:
2- quel valore di MAX_BUF è solo l'ultimo di una serie di tentativi.. 3- hai ragione, ma comunque non è quello il problema perchè è ininfluente.. sinceramente era moltissimo tempo che non usavo l'input da file, quel pezzo l'ho copiato da un sito che l'aveva scritto così e non l'ho più tolto..
__________________
Notebook MSI GT73VR 7RE TITAN SLI: 17.3" 4K IPS @ 120 Hz, i7-7820HK, 2x Nvidia GeForce GTX 1070 (SLI) - 8 GB GDDR5, 2x 16GB DDR4 2.400Mhz, Super Raid 4-512GB NVMe SSD +1TB (SATA) 7200rpm In vendita: |Utenti consigliati|: Marcondiron99 |Utenti sconsigliati|: iltoffa, otherman |
|
|
|
|
|
|
#4 | ||
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12961
|
Aggiungo che apri più volte gli stream (inutilmente).
Codice:
..
/* apre lo stream del file */
stream1 = fopen(unique, "rt");
stream3 = fopen(buoni, "wt");
// apro i files
if ((stream1 = fopen(unique, "rt")) == NULL)
printf("Non posso aprire il file %s\n", unique);
if ((stream3 = fopen(buoni, "wt")) == NULL)
printf("Non posso aprire il file %s\n", buoni);
..
stream2 = fopen(da_togliere, "rt");
if ((stream2 = fopen(da_togliere, "rt")) == NULL)
printf("Non posso aprire il file %s\n", da_togliere);
..
Quote:
Quote:
Il modo corretto per allocare le stringhe c e c2 è: Codice:
variabile = malloc( SIZE ); Si può discutere su quanto dev'essere grande SIZE per contenere la riga ed eventualmente il terminatore, questa è una cosa che dipende dai tuoi files. In ogni caso NON tenerti stretto. Quando fai FGETS, usa al posto di 100 la define che hai utilizzato, meno 1. Codice:
#define SIZE 1024 char *c = malloc( SIZE ); .. fgets(c, SIZE-1, stream); .. Intanto prova a sistemare queste cose, poi vediamo se c'è qualcos'altro che non va. |
||
|
|
|
|
|
#5 | ||
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 3609
|
Quote:
Quote:
il discorso dell'allocazione con c[] e c2[] era solo una prova che avevo fatto per vedere se cambiava qualcosa, ma come per gli altri tentativi non cambia niente, sia in positivo che in negativo, si ferma allo stesso identico punto.. la cosa che non capisco è che le righe sono corte, cioè contengono al massimo 20 caratteri + la newline, meno si di più no... solo che ci sono molte righe nei file, quindi per questo il problema non dovrebbero essere c e c2, perchè tanto non devono memorizzare chissà che frasi chilometriche... ho provato a mettere il fflush(stream2) fuori dal ciclo while dello stream2 ma sempre lo stesso.. la cosa cuoriosa è che il file2 (quello denominato "da togliere" e associato allo stream2) non ha problemi di dimensioni, posso mettergli anche 60000 righe.. invece se nel file1 (denominato "unique" e associato allo stream1) metto più di 1018 righe mi dà errore che "non può aprire il file2", non mi dà errore su se stesso.....
__________________
Notebook MSI GT73VR 7RE TITAN SLI: 17.3" 4K IPS @ 120 Hz, i7-7820HK, 2x Nvidia GeForce GTX 1070 (SLI) - 8 GB GDDR5, 2x 16GB DDR4 2.400Mhz, Super Raid 4-512GB NVMe SSD +1TB (SATA) 7200rpm In vendita: |Utenti consigliati|: Marcondiron99 |Utenti sconsigliati|: iltoffa, otherman |
||
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12961
|
Il problema secondo me è che ad ogni passo del ciclo while apri lo stream2 senza chiuderlo dopo aver finito la lettura (nello stesso ciclo).
Se hai molte righe in stream1 apri tanti descrittori quante sono le righe. Se non chiudi il descrittore, potresti arrivare a saturare il numero massimo di descrittori aperti supportati dal SO. Ora le cose sono 2:
La soluzione 1 è quella più immediata. La soluzione 2 sarebbe anche più efficiente credo, perché eviti di creare ad ogni ciclo un nuovo descrittore. PS: posta il codice modificato. Ultima modifica di WarDuck : 10-12-2011 alle 10:25. |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 3609
|
Quote:
__________________
Notebook MSI GT73VR 7RE TITAN SLI: 17.3" 4K IPS @ 120 Hz, i7-7820HK, 2x Nvidia GeForce GTX 1070 (SLI) - 8 GB GDDR5, 2x 16GB DDR4 2.400Mhz, Super Raid 4-512GB NVMe SSD +1TB (SATA) 7200rpm In vendita: |Utenti consigliati|: Marcondiron99 |Utenti sconsigliati|: iltoffa, otherman Ultima modifica di Balop : 10-12-2011 alle 10:48. |
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jul 2005
Messaggi: 3609
|
ok, ora il programma funziona quasi perfettamente, tranne che l'ultima riga la scrive 2 volte.. e non capisco perchè..
Codice:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_BUF 1024
int main()
{
char *unique= "Unique.txt";
char *da_togliere= "da togliere.txt";
char *buoni= "buoni.txt";
char *c= (char *) malloc(MAX_BUF);
char *c2= (char *) malloc(MAX_BUF);
int num=0;
/* dichiara lo stream e il prototipo della funzione fopen */
FILE *stream1, *stream2, *stream3;
/* apre lo stream del file
stream1 = fopen(unique, "rt");
stream3 = fopen(buoni, "wt");
*/
// apro i files
if ((stream1 = fopen(unique, "rt")) == NULL)
printf("Non posso aprire il file %s\n", unique);
if ((stream3 = fopen(buoni, "wt")) == NULL)
printf("Non posso aprire il file %s\n", buoni);
if ((stream2 = fopen(da_togliere, "rt")) == NULL)
printf("Non posso aprire il file %s\n", da_togliere);
// comincio la scansione dall'inizio del file "da_togliere"
while (!feof(stream1)){
int i=0;
// if (!fgets(c, 3, stream1)) printf("");
fgets(c, MAX_BUF - 1, stream1);
while (!feof(stream2)){
fgets(c2, MAX_BUF - 1, stream2);
if (strcmp(c, c2) == 0) {
i=0;
break;
}
else i=1;
}
if (i==1){
num++;
fputs(c, stream3);
// putc('\n', stream2);
printf("%s", c);
}
(void) fseek(stream2, 0L, SEEK_SET);
}
fflush(stream1);
fclose(stream1);
fflush(stream2);
fclose(stream2);
fflush(stream3);
fclose(stream3);
printf("Numero di righe: %d\n", num);
getchar();
}
Edit: come non detto, su windows funziona perfettamente.. =)
__________________
Notebook MSI GT73VR 7RE TITAN SLI: 17.3" 4K IPS @ 120 Hz, i7-7820HK, 2x Nvidia GeForce GTX 1070 (SLI) - 8 GB GDDR5, 2x 16GB DDR4 2.400Mhz, Super Raid 4-512GB NVMe SSD +1TB (SATA) 7200rpm In vendita: |Utenti consigliati|: Marcondiron99 |Utenti sconsigliati|: iltoffa, otherman Ultima modifica di Balop : 10-12-2011 alle 13:09. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:30.




















