Oppure

Loading
13/05/11 11:11
Pitagora
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?

#include <stdio.h>
#include <stdlib.h>
#ifndef RANGE
#define RANGE 100000 /* sostituire 100000 con un numero più alto per aumentare la capienza */
#endif

void ottieni (int *);

int main()
{
	int max = 0, contatore = 0;
	int i, j;
	FILE *testo = fopen ("file.txt", "w");
	int *n_primi_low = malloc (sizeof (int) * RANGE);
	int *n_primi;
	
	if (!n_primi_low) exit (EXIT_FAILURE);
	
	ottieni (n_primi_low);
	
	for (i = 0, j = 0; i <= RANGE; i++) 
	{
		if (! n_primi_low[i]) continue;
		else {
			max += 1;
			n_primi[j] = n_primi_low[i];
			j += 1;
		}
	}
	
	free (n_primi_low);
	n_primi = malloc (sizeof (int) * max);
	if (!n_primi) exit (EXIT_FAILURE);
	i = 2; j = 3;
	
	fprintf (testo, "2 --> 3\n");
	
	while (contatore <= max) 
	{
		if ( (n_primi[j] - n_primi[i]) == 2)
			fprintf (testo, "%d --> %d\n", n_primi[i], n_primi[j]); /* inserisco dentro il file tutti i numeri gemelli */
		
		j += 1; i += 1; contatore += 1;
	}
	
	fclose (testo);
	free (n_primi);
	
	return 0;

}

void ottieni (int *n_prime) 
{	
	int a, b;
	int counter = 3, index = 0;
	
	n_prime[index] = 2; /* questo e' l'unico numero primo non dispari */
	index += 1;
	
	while (counter <= RANGE) 
	{
		n_prime[index] = counter;
		
		counter += 2;
		index += 1;
	}
	
	for (a = 3; a <= RANGE; a++) 
	{	
		for (b = a + 1; b <= RANGE; b++) 
		{
			if ( (n_prime[b] % a) == 0) 
				n_prime[b] = 0;
		}
	}
}
Ultima modifica effettuata da Pitagora 13/05/11 11:14
aaa
13/05/11 11:26
HeDo

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?

aaa
13/05/11 11:41
Pitagora
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!
aaa
13/05/11 12:49
pierotofy
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 13/05/11 12:50
Il mio blog: piero.dev
13/05/11 12:52
TheKaneB
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.
aaa
13/05/11 14:52
Alex
Postato originariamente da TheKaneB:

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


senza nulla togliere ai piedi però!!!:k::k::k:
aaa
14/05/11 11:49
Pitagora
ok, ho fatto le modifiche appropriate.

adesso è così:
#include <stdio.h>
#include <stdlib.h>
#ifndef RANGE
#define RANGE 1000 /* sostituire 1000 con un numero più alto per aumentare la capienza */
#endif

void ottieni (int *);

int main()
{
    int max = 0, contatore = 0;
    int i, j;
    FILE *testo = fopen ("file.txt", "w");
    int *n_primi_low = malloc (sizeof (int) * RANGE);
    int *n_primi;
    
    if (!n_primi_low) exit (EXIT_FAILURE);
    
    ottieni (n_primi_low);
    
    for (i = 0; i <= RANGE; i++) 
    {
        if (! n_primi_low[i]) continue;
        else {
            max += 1;
        }
    }

    n_primi = malloc (sizeof (int) * max);
    if (!n_primi) exit (EXIT_FAILURE);

	for (i = 0, j = 0; i <= RANGE; i++) 
	{
		if (! n_primi_low[i]) continue;
		else {
			n_primi[j] = n_primi_low[i];
			j += 1;
		}
	}
	free (n_primi_low);

    i = 2; j = 3;
    
    fprintf (testo, "2 --> 3\n");
    
    while (contatore <= max) 
    {
        if ( (n_primi[j] - n_primi[i]) == 2)
            fprintf (testo, "%d --> %d\n", n_primi[i], n_primi[j]); /* inserisco dentro il file tutti i numeri gemelli */
        
        j += 1; i += 1; contatore += 1;
    }
    
    fclose (testo);
    free (n_primi);
    
    return 0;

}

void ottieni (int *n_prime) 
{    
    int a, b;
    int counter = 3, index = 0;
    
    n_prime[index] = 2; /* questo e' l'unico numero primo non dispari */
    index += 1;
    
    while (counter <= RANGE) 
    {
        n_prime[index] = counter;
        
        counter += 2;
        index += 1;
    }
    
    for (a = 3; a <= RANGE; a++) 
    {    
        for (b = a + 1; b <= RANGE; b++) 
        {
            if ( (n_prime[b] % a) == 0) 
                n_prime[b] = 0;
        }
    }
}


Adesso il programma si avvia e si conclude normalmente. Se modifico il RANGE sostituendolo con 10000, una volta compilato ed avviato, mi esce scritto:
Windows ha generato un punto di interruzione in aaa.exe.

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.

È anche possibile che l'utente abbia premuto F12 mentre aaa.exe era attivo.

Controllare la finestra di output per ulteriori informazioni diagnostiche.


Il sorgente mi sembra apposto!
Ultima modifica effettuata da Pitagora 14/05/11 13:40
aaa
14/05/11 17:40
pierotofy
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:

int *n_primi_low = malloc (sizeof (int) * (RANGE + 1));
Il mio blog: piero.dev