Newsgroup: it.comp.lang.c
Titolo: errore programma

Salve,
ho il dev c++ e win98.
Ho scritto questo programma:
INIZIO  PROGRAMMA
////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* questo programma converte un vettore di byte in un vettore di interi,
creati
a partire dai byte  */
/* ora noi descriviamo il prototipo delle funzioni */
int* converti_segnale(unsigned char* vettore_wav, int N1, int n_byte );
/* ora comincia il main */
main()
{
const int N1=32;
int  i, n_bit, n_byte;
unsigned char *vettore_wav;
int *segnale_int;
/* N1 è il n° caratteri = byte dei campioni audio nel vettore "vettore_wav"
*/
/* "segnale_int" è il vettore gestito a interi che contenga 1 intero per
ogni campione audio, creato
 combinando i byte di "vettore_wav" associati ad esso */
/* "vettore_wav" è il vettore gestito a caratteri, che contenga n_byte
caratteri, per ogni
 campione audio */
/* n_byte è il n° byte di vettore_wav associati ad ogni campione audio  */
/*
per testare la correttezza della funzione nel caso n_bit=8 o n_bit=16,
rimuovere i simboli di commento davanti ad n_bit che si desidera testare
*/
n_bit=8;
//n_bit=16;
n_byte=n_bit/8;
vettore_wav=(unsigned char*)malloc(sizeof(unsigned char)*N1);
/*
ora viene creata la sequenza dei byte associati ai campioni audio.
Questa sequenza è ipersemplice e tale da creare:
-nel caso a 16 bit:
la prima metà dei campioni audio è negativa:  segnale[i]=255-i;
la seconda metà dei campioni audio è positiva:  segnale[i]=i;
-nel caso a 8 bit:
nella prima metà dei campioni audio si alternano i valori "0" e
segnale[i]=255-i che è negativo;
nella seconda metà dei campioni audio si alternano i valori "0" e
segnale[i]=i che è positivo;
Eseguendo il programma, in effetti si ottengono proprio questi valori.
Pertanto
il codice si comporta correttamente.
*/
/* il ciclo che segue crea la prima metà dei campioni audio  */
for(i=0;i<(N1/2);i=i+2)
{
vettore_wav[i]=255-i;
vettore_wav[i+1]=0;
}
/* il ciclo che segue crea la prima metà dei campioni audio */
for(i=(N1/2);i<N1;i=i+2)
{
vettore_wav[i]=i;
vettore_wav[i+1]=0;
}
/* ora viene creato il vettore "segnale_int" di interi con i campioni audio
 del tipo intero */
segnale_int=converti_segnale(vettore_wav, N1, n_byte);
/*
La seguente printf() consente di stampare i valori interi associati ad ogni
campione audio. Per stampare i campioni audio diversi, basta cmbiare
l'indice
del vettore all'interno della printf().
*/
printf("%d\n", segnale_int[64]); getchar();
}
////////////////////////////////////////////////////////////////////////////
//
int* converti_segnale(unsigned char* vettore_wav, int N1, int n_byte )
{
/*
Questa funzione presenta 3 parametri di ingresso: vettore_wav, N1, n_byte ed
ha
1 parametro di uscita segnale_int.
questa funzione crea il vettore "segnale" di interi, a partire dal vettore
vettore_wav di caratteri, entrambi contenenti solo i campioni audio.
i: il campione audio considerato
j: il byte considerato del campione audio i_esimo
segnale: il vettore dove ogni campione audio del file wav sia gestito con il
tipo "int" indipendentemente da n_bit
modulo: il modulo del campione audio attuale. Questa variabile viene
impiegata
solo se il campione audio sia negativo
valore: il valore intero del campione audio attuale, ricreato a partire dai
suoi byte
v_appoggio: il vettore di appogio che contiene e gestisce come i caratteri i
byte del modulo
del campione audio attuale. Esso viene impiegato solo se il campione audio
attuale
sia negativo
N2 è il n° campioni audio = n° elementi del vettore "segnale"
N1 è il n° caratteri = byte dei campioni audio nel vettore "vettore_wav"
"segnale_int" è il vettore gestito a interi che contenga 1 intero per ogni
campione audio, creato
 combinando i byte di "vettore_wav" associati ad esso
"vettore_wav" è il vettore gestito a caratteri, che contenga n_byte
caratteri, per ogni
 campione audio, creato combinando i byte di "vettore_wav" associati ad esso
n_byte è il n° byte di vettore_wav associati ad ogni campione audio
*/
int n_bit, i, j, modulo, valore, size_int, N2;
unsigned char *v_appoggio;
int *segnale_int;
N2=N1/n_byte;
size_int=sizeof(int);
v_appoggio=(unsigned char*)malloc(sizeof(unsigned char)*size_int);
if((segnale_int=(int*)malloc(size_int*N2))==NULL)
{
printf("errore. c'è poca RAM libera per eseguire il programma\n");
exit(1);
}
/* il ramo "if" che segua va svolto solo se n_bit=8 */
if(n_byte==1)
{
/*
il ciclo che segua, serve per togliere l'offset "128" dai valori dei
campioni
audio, che venga aggiunto ad essi, nel creare i file wav, solo se n_bit=8
*/
for(i=0;i<N2;i++)
{
vettore_wav[i]=vettore_wav[i]-128;
}
}
/*
il ciclo che segua va svolto qualunque sia il valore di n_byte, perchè è di
validità
generale. Esso crea il vettore "segnale", combinando i caratteri del vettore
"vettore_wav"
Per ogni campione audio i-esimo va creato il valore intero corrispondente, a
partire di byte ad esso associati contenuti nel file wav
*/
for(i=0;i<N2;i++)
{
/*
se il campione audio attuale i-esimo sia negativo allora  va svolto solo il
ramo "if" che segua. Altrimenti si esegue il ramo "else". Per verificare
ciò, basta verificare
se il MSBit del MSByte del campione audio attuale i-esimo, sia 1, il che
equivale a
verificre se il MSByte sia > 128.
 */
if (vettore_wav[(i+1)*n_byte-1]>128)
{
//printf("%d\n", vettore_wav[(i+1)*n_byte-1]); getchar();
//system("pause");
/*
se il campione audio attuale i-esimo sia negativo, allora per risalire al
suo valore intero complessivo di suoi byte, serve ricavarne il modulo. Al
tale fine, serve passare per v_appoggio.
Per ricavarne il modulo,
serve eliminre il formato complemento a 2, sottraendo il campione audio ad
n_byte, dal valore 256^n_byte. Ciò equivale a sottrarre il MSByte
(vettore_wav[(i+1)*n_byte-1]) da 256, e gli altri byte da 255.
Queste sottrazioni byte a byte possono essere svolte
nell'ordine che ci pare, perchè sono tali da non richiedere mai il bit di
riporto, visto che il sottraendo è massimo per ogni byte
*/
/*
il ciclo che segue calcola il modulo del campione audio negativo i-esimo .
Ecco come si passa da "valore_complemento_a_2" a "modulo" :
modulo=(111111...1111)-(valore_complemento_a_2)+1;
*/
modulo=0;
for(j=0;j<n_byte;j++)
{
v_appoggio[j]=255-vettore_wav[i*n_byte+j];
modulo=modulo+v_appoggio[j]*(int)pow(256,j);
}
valore=-(modulo+1);
/*
la variabile "valore" conterrà il valore, in formato complemento a 2, perchè
ciò
viene svolto dalla istruzione di assegnamento
*/
}
/*
 il ramo "else " che segua, va svolto solo se se il campione audio attuale
i-esimo
 sia positivo.
 */
else
{
/*
se il campione audio attuale sia positivo, allora non c'è bisogno di creare
v_appoggio. il ciclo che segua, crea il valore positivo del campione audio a
partire dai suoi byte.
*/
valore=0;
for(j=0;j<n_byte;j++)
{
valore=valore+ vettore_wav[i*n_byte+j]*(int)pow(256,j);
}
/*
ora, indipendentemente che si sia percorso il ramo "if" o "else", si
aggiorna
l'elemento  segnale[i]
*/
}
segnale_int[i]=valore;
} //fine ciclo
printf("arrivato"); getchar();
}
////////////////////////////////////////////////////////////
FINE PROGRAMMA
compila corretto. però in esecuzione il windows mi dà  errore.
L'aspetto strano è che, mandandolo in esecuzione, prima di darmi errore, mi
stampa: "arrivato",
che è posto alla fine della funzione "converti_segnale", come potete
osservare.
Temo che il problema stia quando esce da questa funzione, per ritornare al
main():
Ma non capisco dove stia il problema.
grazie,
adriano

 
Il problema, Adriano, è che devi imparare a fare debugging. Quando un
programma non si comporta come immagini, non puoi scoprire il problema
contemplando il sorgente. Devi eseguirlo passo-passo, guardare che valori
assumono le variabili, e verificare se accade proprio quello che tu pensi
che debba accadere.
Nel programma in questione, all'interno della funzione 'converti_segnale' la
malloc alloca un array di lunghezza sizeof(int)*32 (utilizzabile, quindi,
come un array di 32 int), mentre la tua printf finale assume che l'array di
int abbia almeno 65 elementi. Il motivo lo scopri seguendo tutti le
operazioni che portano N2 ad avere il valore di 32.
Max

 Il problema, Adriano, è che devi imparare a fare debugging.
Il problema, Max, è che ogni volta che provo ad usare il debugger di dev
c++, il win98 mi va in crash, quindi non l'ho mai potuto impiegare. Cmq
grazie. Conosci debugger free alternativi per win98?
adriano

 c++, il win98 mi va in crash, quindi non l'ho mai potuto impiegare.
Capisco. Quindi usi il newsgroup come debugger distribuito? :)
Ad ogni modo, fare debugging non significa necessariamente usare un
debugger. Anche solo stampare i valori di alcune variabili con printf per
capire che cosa succede durante l'esecuzione può aiutarti a scoprire dov'è
il bug.
Max