Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - il mio programma si blocca su windows, su ubuntu no
Forum - C/C++ - il mio programma si blocca su windows, su ubuntu no

Avatar
Pitagora (Member)
Expert


Messaggi: 367
Iscritto: 12/06/2010

Segnala al moderatore
Postato alle 13:11
Venerdì, 13/05/2011
Salve a tutti. Ho scritto questo programmino, senza richiamare nessuna funzione dipendente dal sistema. Compilando e avviandolo su ubuntu, nessun problema. Su windows 7 il programma, una volta compilato ed avviato si pianta! Perchè tutto questo?

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #ifndef RANGE
  4. #define RANGE 100000 /* sostituire 100000 con un numero più alto per aumentare la capienza */
  5. #endif
  6.  
  7. void ottieni (int *);
  8.  
  9. int main()
  10. {
  11.         int max = 0, contatore = 0;
  12.         int i, j;
  13.         FILE *testo = fopen ("file.txt", "w");
  14.         int *n_primi_low = malloc (sizeof (int) * RANGE);
  15.         int *n_primi;
  16.        
  17.         if (!n_primi_low) exit (EXIT_FAILURE);
  18.        
  19.         ottieni (n_primi_low);
  20.        
  21.         for (i = 0, j = 0; i <= RANGE; i++)
  22.         {
  23.                 if (! n_primi_low[i]) continue;
  24.                 else {
  25.                         max += 1;
  26.                         n_primi[j] = n_primi_low[i];
  27.                         j += 1;
  28.                 }
  29.         }
  30.        
  31.         free (n_primi_low);
  32.         n_primi = malloc (sizeof (int) * max);
  33.         if (!n_primi) exit (EXIT_FAILURE);
  34.         i = 2; j = 3;
  35.        
  36.         fprintf (testo, "2 --> 3\n");
  37.        
  38.         while (contatore <= max)
  39.         {
  40.                 if ( (n_primi[j] - n_primi[i]) == 2)
  41.                         fprintf (testo, "%d --> %d\n", n_primi[i], n_primi[j]); /* inserisco dentro il file tutti i numeri gemelli */
  42.                
  43.                 j += 1; i += 1; contatore += 1;
  44.         }
  45.        
  46.         fclose (testo);
  47.         free (n_primi);
  48.        
  49.         return 0;
  50.  
  51. }
  52.  
  53. void ottieni (int *n_prime)
  54. {      
  55.         int a, b;
  56.         int counter = 3, index = 0;
  57.        
  58.         n_prime[index] = 2; /* questo e' l'unico numero primo non dispari */
  59.         index += 1;
  60.        
  61.         while (counter <= RANGE)
  62.         {
  63.                 n_prime[index] = counter;
  64.                
  65.                 counter += 2;
  66.                 index += 1;
  67.         }
  68.        
  69.         for (a = 3; a <= RANGE; a++)
  70.         {      
  71.                 for (b = a + 1; b <= RANGE; b++)
  72.                 {
  73.                         if ( (n_prime[b] % a) == 0)
  74.                                 n_prime[b] = 0;
  75.                 }
  76.         }
  77. }


Ultima modifica effettuata da Pitagora il 13/05/2011 alle 13:14
PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2765
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 13:26
Venerdì, 13/05/2011

ma che vuol dire si pianta? che fa? errore? crasha? hai fatto debug per capire la linea? hai dato i permessi in lettura / scrittura al file?


PM Quote
Avatar
Pitagora (Member)
Expert


Messaggi: 367
Iscritto: 12/06/2010

Segnala al moderatore
Postato alle 13:41
Venerdì, 13/05/2011
Hai ragione, non ho specificato! Il programma si avvia tranquillamente ma dopo un paio di secondi esce il messaggio: il programma non risponde ... il programma ha i permessi di lettura e scrittura perchè mi crea il file ma con niente scritto all'interno!

PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 14:49
Venerdì, 13/05/2011
int *n_primi non e' allocato prima di essere usato alla linea 26. Hai probabilmente avuto fortuna che gcc ha piazzato il tuo puntatore in uno spazio che (forse) non interferisce con il resto del codice. Probabilmente il compilatore che hai usato su Windows invece ha messo il puntatore vicino ad altri dati e quando accedi uno degli indici e ci scrivi sopra, stai probabilmente sovvrascrivendo sopra altri dati, con effetti imprevedibili.

Ultima modifica effettuata da pierotofy il 13/05/2011 alle 14:50


Il mio blog: https://piero.dev
PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 14:52
Venerdì, 13/05/2011
scrivi sull'array n_primi durante il primo ciclo for, ma lo allochi soltanto dopo il ciclo.

Ubuntu, dal momento che Linux ragiona un po' coi piedi, non si fa scrupoli e ti consente comunque di scrivere su chissà che chunk di memoria casuale, che alla fine funziona solo per una spudorata coincidenza.
Windows, invece, si incazza correttamente e non concede al programma il privilegio di scrivere a muzzo in Ram non inizializzata.

PM Quote
Avatar
Alex (Ex-Member)
Expert


Messaggi: 441
Iscritto: 15/08/2005

Segnala al moderatore
Postato alle 16:52
Venerdì, 13/05/2011
Testo quotato

Postato originariamente da TheKaneB:

Ubuntu, dal momento che Linux ragiona un po' coi piedi,  



senza nulla togliere ai piedi però!!!:k::k::k:

PM Quote
Avatar
Pitagora (Member)
Expert


Messaggi: 367
Iscritto: 12/06/2010

Segnala al moderatore
Postato alle 13:49
Sabato, 14/05/2011
ok, ho fatto le modifiche appropriate.

adesso è così:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #ifndef RANGE
  4. #define RANGE 1000 /* sostituire 1000 con un numero più alto per aumentare la capienza */
  5. #endif
  6.  
  7. void ottieni (int *);
  8.  
  9. int main()
  10. {
  11.     int max = 0, contatore = 0;
  12.     int i, j;
  13.     FILE *testo = fopen ("file.txt", "w");
  14.     int *n_primi_low = malloc (sizeof (int) * RANGE);
  15.     int *n_primi;
  16.    
  17.     if (!n_primi_low) exit (EXIT_FAILURE);
  18.    
  19.     ottieni (n_primi_low);
  20.    
  21.     for (i = 0; i <= RANGE; i++)
  22.     {
  23.         if (! n_primi_low[i]) continue;
  24.         else {
  25.             max += 1;
  26.         }
  27.     }
  28.  
  29.     n_primi = malloc (sizeof (int) * max);
  30.     if (!n_primi) exit (EXIT_FAILURE);
  31.  
  32.         for (i = 0, j = 0; i <= RANGE; i++)
  33.         {
  34.                 if (! n_primi_low[i]) continue;
  35.                 else {
  36.                         n_primi[j] = n_primi_low[i];
  37.                         j += 1;
  38.                 }
  39.         }
  40.         free (n_primi_low);
  41.  
  42.     i = 2; j = 3;
  43.    
  44.     fprintf (testo, "2 --> 3\n");
  45.    
  46.     while (contatore <= max)
  47.     {
  48.         if ( (n_primi[j] - n_primi[i]) == 2)
  49.             fprintf (testo, "%d --> %d\n", n_primi[i], n_primi[j]); /* inserisco dentro il file tutti i numeri gemelli */
  50.        
  51.         j += 1; i += 1; contatore += 1;
  52.     }
  53.    
  54.     fclose (testo);
  55.     free (n_primi);
  56.    
  57.     return 0;
  58.  
  59. }
  60.  
  61. void ottieni (int *n_prime)
  62. {    
  63.     int a, b;
  64.     int counter = 3, index = 0;
  65.    
  66.     n_prime[index] = 2; /* questo e' l'unico numero primo non dispari */
  67.     index += 1;
  68.    
  69.     while (counter <= RANGE)
  70.     {
  71.         n_prime[index] = counter;
  72.        
  73.         counter += 2;
  74.         index += 1;
  75.     }
  76.    
  77.     for (a = 3; a <= RANGE; a++)
  78.     {    
  79.         for (b = a + 1; b <= RANGE; b++)
  80.         {
  81.             if ( (n_prime[b] % a) == 0)
  82.                 n_prime[b] = 0;
  83.         }
  84.     }
  85. }



Adesso il programma si avvia e si conclude normalmente. Se modifico il RANGE sostituendolo con 10000, una volta compilato ed avviato, mi esce scritto:
Codice sorgente - presumibilmente C/C++

  1. Windows ha generato un punto di interruzione in aaa.exe.
  2.  
  3. Ciò può essere dovuto a un danneggiamento dell'heap che indica un bug in aaa.exe o in una qualunque delle DLL che ha caricato.
  4.  
  5. È anche possibile che l'utente abbia premuto F12 mentre aaa.exe era attivo.
  6.  
  7. Controllare la finestra di output per ulteriori informazioni diagnostiche.



Il sorgente mi sembra apposto!

Ultima modifica effettuata da Pitagora il 14/05/2011 alle 15:40
PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 19:40
Sabato, 14/05/2011
Codice sorgente - presumibilmente C/C++

  1. for (i = 0; i <= RANGE; i++)



Se fai bene i tuoi calcoli, tu stai allocando RANGE * sizeof(int) bytes di spazio, ma poi esegui dei loop che utilizzano RANGE + 1 elementi.

Puoi risolvere facendo:

Codice sorgente - presumibilmente C/C++

  1. int *n_primi_low = malloc (sizeof (int) * (RANGE + 1));



Il mio blog: https://piero.dev
PM Quote
Avatar
Pitagora (Member)
Expert


Messaggi: 367
Iscritto: 12/06/2010

Segnala al moderatore
Postato alle 9:37
Domenica, 15/05/2011
eh si si mi ero accorto. Grazie comunque :k:

PM Quote