Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo
Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo
Per diversi giorni il Galaxy S26 Ultra di Samsung è stato il nostro compagno di vita. Oltre alle conferme del colosso coreano come la qualità del display e una suite AI senza rivali, arriva il Privacy Display, un unicum nel mondo smartphone. Ci sono ancora alcuni gap che non sono riusciti a colmare lato batteria e fotocamera, seppur con alcuni miglioramenti.
Diablo II Resurrected: il nuovo DLC Reign of the Warlock
Diablo II Resurrected: il nuovo DLC Reign of the Warlock
Abbiamo provato per voi il nuovo DLC lanciato a sorpresa da Blizzard per Diablo II: Resurrected e quella che segue è una disamina dei nuovi contenuti che abbiamo avuto modo di sperimentare nel corso delle nostre sessioni di gioco, con particolare riguardo per la nuova classe dello Stregone
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Siamo tornati nel parco tecnologico di Trieste per il kick-off del programma che mette a disposizione di cinque startup le infrastrutture di ricerca, dal sincrotrone Elettra ai laboratori di genomica e HPC. Roberto Pillon racconta il modello e la visione
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 09-12-2011, 19:12   #1
Balop
Senior Member
 
L'Avatar di Balop
 
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);
}
senza la malloc, dichiarando c e c2 [100000..] è sempre la stessa cosa, al massimo se metto un numero troppo grande mi dà segment fault in fase di compilazione..
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
Balop è offline   Rispondi citando il messaggio o parte di esso
Old 09-12-2011, 19:19   #2
GByTe87
Senior Member
 
L'Avatar di GByTe87
 
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.
GByTe87 è offline   Rispondi citando il messaggio o parte di esso
Old 09-12-2011, 19:31   #3
Balop
Senior Member
 
L'Avatar di Balop
 
Iscritto dal: Jul 2005
Messaggi: 3609
Quote:
Originariamente inviato da GByTe87 Guarda i messaggi
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
1- No scusa era un altro errore, ma nel caso dichiarassi char c[1000.....].
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
Balop è offline   Rispondi citando il messaggio o parte di esso
Old 10-12-2011, 09:02   #4
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
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);
..
Basta mantenere solo la seconda (la variante con l'IF).

Quote:
Originariamente inviato da Balop Guarda i messaggi
1- No scusa era un altro errore, ma nel caso dichiarassi char c[1000.....].
Non puoi allocare staticamente più di TOT bytes, in quanto esiste un limite finito per lo stack.

Quote:
Originariamente inviato da Balop Guarda i messaggi
2- quel valore di MAX_BUF è solo l'ultimo di una serie di tentativi..
Andare a tentativi senza capire quello che stai facendo non è il massimo.

Il modo corretto per allocare le stringhe c e c2 è:

Codice:
variabile = malloc( SIZE );
Dove SIZE è espresso in bytes (quindi non hai bisogno del sizeof se stai usando caratteri ASCII).

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);
..
Per definizione FGETS si ferma quando incontra una new-line.

Intanto prova a sistemare queste cose, poi vediamo se c'è qualcos'altro che non va.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 10-12-2011, 09:49   #5
Balop
Senior Member
 
L'Avatar di Balop
 
Iscritto dal: Jul 2005
Messaggi: 3609
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
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);
..
Basta mantenere solo la seconda (la variante con l'IF).
Facendo questo sono salito a poter inserire nel file1 1018 righe...


Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Non puoi allocare staticamente più di TOT bytes, in quanto esiste un limite finito per lo stack.



Andare a tentativi senza capire quello che stai facendo non è il massimo.

Il modo corretto per allocare le stringhe c e c2 è:

Codice:
variabile = malloc( SIZE );
Dove SIZE è espresso in bytes (quindi non hai bisogno del sizeof se stai usando caratteri ASCII).

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);
..
Per definizione FGETS si ferma quando incontra una new-line.

Intanto prova a sistemare queste cose, poi vediamo se c'è qualcos'altro che non va.
inizialmente le stringhe le avevo allocate con la malloc (anche se avevo usato SIZEOF * MAX_BUF)
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
Balop è offline   Rispondi citando il messaggio o parte di esso
Old 10-12-2011, 10:23   #6
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
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:
  1. Chiudi stream2 all'interno del ciclo dopo averlo usato
  2. Apri stream2 una volta sola, così come hai fatto per gli altri stream e usi qualche funzione per resettare lo stream ad ogni ciclo di lettura (forse fseek fa al caso tuo)

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.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 10-12-2011, 10:43   #7
Balop
Senior Member
 
L'Avatar di Balop
 
Iscritto dal: Jul 2005
Messaggi: 3609
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
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:
  1. Chiudi stream2 all'interno del ciclo dopo averlo usato
  2. Apri stream2 una volta sola, così come hai fatto per gli altri stream e usi qualche funzione per resettare lo stream ad ogni ciclo di lettura (forse fseek fa al caso tuo)

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.
lo stream2 lo riaprivo ogni volta perchè altrimenti non funzionava bene il programma (non conoscevo la funzione che mi hai detto ora..), quindi riaprendolo ogni volta ricomincia la ricerca sempre dall'inizio.. avevo pensato di mettere la funziona fflush lì alla fine del ciclo while ma non la funzione fclose!! in questo modo sembra funzionare anche se ci sta un po a terminare l'ultima riga e mette un doppione (cosa che avevo visto pure prima ma di secondaria importanza..), anche se comunque ci sta un bel po, ora vedo come funziona la fseek e apro lo stream fuori, dovrebbe risultare più veloce il programma... ti faccio sapere.. intanto grazie
__________________
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.
Balop è offline   Rispondi citando il messaggio o parte di esso
Old 10-12-2011, 12:16   #8
Balop
Senior Member
 
L'Avatar di Balop
 
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();
}
all'inizio del primo ciclo while ho aggiunto la dichiarazione i=0 per evitare che restasse in qualche modo memorizzata con il valore 1.. invece niente.. l'ultima riga viene sempre duplicata.. l'ultimo aiutino??

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.
Balop è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo Recensione Samsung Galaxy S26 Ultra: finalmente ...
Diablo II Resurrected: il nuovo DLC Reign of the Warlock Diablo II Resurrected: il nuovo DLC Reign of the...
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup Deep Tech Revolution: così Area Science P...
HP OMEN MAX 16 con RTX 5080: potenza da desktop replacement a prezzo competitivo HP OMEN MAX 16 con RTX 5080: potenza da desktop ...
Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta Recensione Google Pixel 10a, si migliora poco ma...
Le analisi di ALMA sulla cometa interste...
La missione cinese Tianwen-3 per portare...
Un satellite di HEO Space ha catturato u...
Mini LED 144Hz a prezzo folle: questo Hi...
Novità per Fortinet: arrivano For...
Volkswagen e Xpeng, il SUV è real...
Volkswagen ribattezza ID.3 e le dà un mo...
Aruba rende disponibile VMware Hosted Pr...
Questa Olympus da 20 MP con stabilizzazi...
Il nuovo dispositivo di Rabbit si chiama...
'Se avete RAM, siamo pronti ad acquistar...
Veeam corregge diverse vulnerabilit&agra...
MacBook Neo segna una svolta per Apple: ...
Polestar pubblica il report LCA di Poles...
Il rame non basta più: NVIDIA, AM...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 01:20.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v