Newsgroup: it.comp.lang.c++
Titolo: Access Violation su vector

Buongiorno a tutti,
di seguito espongo il problema nei dettagli, scusate se risulto prolisso.
Sto scrivendo un programma in C++ che preleva da un file txt i campioni di 
un file audio wav al fine di implementare un effetto sonoro secondo la 
scelta dell'utente.
Per realizzare l'effetto devo utilizzare una linea di ritardo modulata e qui 
sorge il problema :
praticamente quando vado ad eseguire la riga :
		y.push_back(x[(int) (i - D[i])]);
in fase di esecuzione ottengo la classica finestra di windows per la 
segnalazione di errore.
Facendo il debug il compilatore (Microsoft Visual C++ 6) mi indica la 
suddetta riga con errore :
Unhandled exception in Effetti.exe : 0xC0000005 : Access Violation
Per quel che so, questo problema si verifica quando si tenta di accedere a 
spazi di memoria non disponibili o quando si superano i limiti dell'array.
Nel mio caso utilizzo dei vector con funzione di libreria pushback onde 
evitare il problema della memoria.
Mi viene da escludere anche il problema dell'indirizzamento in quanto, se 
inserisco nel ciclo for un cout, in fase di esecuzione ottengo la stampa di 
circa 30 valori e poi si blocca.
Di seguito posto il codice, la riga in oggetto si trova al n.54 per 
l'effetto Vibrato e al n.65 per il flanging.
Qualsiasi suggerimento utile č gradito,
vi ringrazio in anticipo.
#include <iostream>
#include <vector>
#include <math.h>
#define PI 3.1416		// Costante
using namespace std;
class Effetto {
public:
	FILE *input, *output;
	vector<float> x;
	vector<float> D;
	vector<float> y;
	int M, fzero;	int 
a, g, d0, d1, f;	Effetto();
	~Effetto();
void modulazione(vector<float> D,int M,int fzero,int counter);	// Prototipi 
delle funzioni di
void mod(vector<float> D, int d0, int d1, int f, int counter);	// 
modulazione
void vibrato(FILE *output,vector<float> x,vector<float> D,vector<float> 
y,int counter); // Funzioni per gli effetti
void flanging(FILE *output,vector<float> D,vector<float> x,vector<float> y, 
int g, int counter);
};
Effetto::Effetto() {}
Effetto::~Effetto() {}
void Effetto::modulazione(vector<float> D,int M,int fzero,int counter) {  // 
Modulazione del vibrato
	int i;	for ( i = 0; i < counter ; i++ ){
		D.push_back((( M/2 ) * (float) sin(2*PI*fzero*i))  + ( M/2 ));
	}
}
void Effetto::mod(vector<float> D, int d0, int d1, int f, int counter) // 
Funzione di modulazione per il flangin
{
	int i;
	for ( i = 0; i < counter; i++){
	D.push_back(d0 + d1*(float)sin(2*PI*f*i));
	}
}
void Effetto::vibrato(FILE *output,vector<float> x,vector<float> 
D,vector<float> y,int counter)
{	// Funzione per il calcolo dei nuovi campioni e scrittura sul file di 
output
	int i;
	for ( i = 0; i < counter; i++ ){
		y.push_back(x[(int) (i - D[i])]);
		fprintf(output,"%f\n",y[i]);
	}
}
void Effetto::flanging(FILE *output,vector<float> D, vector<float> 
x,vector<float> y, int g, int counter)
	{	// Output sul file dei nuovi campioni
	int i;
	for ( i = 0; i < counter; i++)
	{
	y.push_back(x[i] + g*x[(int)(i-D[i])]);
	fprintf(output,"%f\n",y[i]);
	}
}
int main()
{
	Effetto uno; // Istanzio l'oggetto
	int choice = 0;
	float temp;
	int counter;
	cout << "\t\t              ******************\n";
	cout << "\t\t ************ Vibrato e Flanging ************\n";
	cout << "\t\t              ******************\n\n";
	cout << "Ho creato l'oggetto \n";
	cout << "Per realizzare l'effetto Vibrato digitare  : 1\n";
	cout << "Per realizzare l'effetto Flanging digitare : 2\n";
	cin >> choice;
	if ( choice == 1 ) {
	cout << "Hai scelto il Vibrato " << endl;
		// Inserimento valori
	cout << "Inserire M : \n";
	cin >> uno.M;
	cout << "Inserire fzero : \n";
	cin >> uno.fzero;
	cout << endl;
	uno.input = fopen("soundIN.txt","r");
		if ( uno.input == NULL ) {
		cout << "Errore apertura file \n" ;
		exit(1);
	}
	uno.output = fopen("soundOUT.txt","w");
		if ( uno.output == NULL ) {
		cout << "Errore apertura file \n" ;
		exit(1);
	}
		// Prelievo campioni dal file
	while ( fscanf(uno.input,"%f\n",&temp) != -1 ) {
		uno.x.push_back(temp);
	}
	cout <<"Numero campioni individuati : " << uno.x.size() << endl;
	counter = uno.x.size(); // Onde evitare numerose chiamate di funzione size 
si utilizza la variabile
						   // counter
	uno.modulazione(uno.D,uno.M,uno.fzero,counter);
	cout << "Modulazione Eseguita";
	uno.vibrato(uno.output,uno.x,uno.D,uno.y,counter);
	}
	if ( choice == 2 ) {
	cout << "Inserire il valore di g\n";
	cin >> uno.g;
	cout << "Inserire il valore di d0:\n";
	cin >> uno.d0;
	cout << "Inserire il valore di d1: \n";
	cin >> uno.d1;
	cout << "Inserire il valore di f: \n";
	cin >> uno.f;
	uno.input = fopen("soundIN.txt","r");
		if ( uno.input == NULL ) {
		cout << "Errore apertura file \n" ;
		exit(1);
	}
	uno.output = fopen("soundOUT.txt","w");
		if ( uno.output == NULL ) {
		cout << "Errore apertura file \n" ;
		exit(1);
	}
		// Prelievo campioni dal file
	while ( fscanf(uno.input,"%f\n",&temp) != -1 ) {
		uno.x.push_back(temp);
	}
	cout <<"Numero campioni individuati : " << uno.x.size() << endl;
	counter = uno.x.size(); // Onde evitare numerose chiamate di funzione size 
si utilizza la variabile
						   // counter
	uno.mod(uno.D,uno.d0,uno.d1,uno.f,counter);	// Modulazione
	uno.flanging(uno.output,uno.D,uno.x,uno.y,uno.g,counter);	// Output effetto 
flanger
	} // endif
	fclose(uno.input);
	fclose(uno.output);
	return 0;
}
 

 }
Non sembra legato al problema che riporti, ma questa funzione non serve 
a niente. Gli passi degli argomenti su cui fa dei conti e poi butti via 
il risultato...
E.

 ha scritto nel messaggio 
news:Oq4rl.51315$8Z....@tornado.fastwebnet.it...


 Intendevi forse che c'č qualche errore semantico in questa parte di codice?
Sě, perché la funzione modifica una copia del vettore D e poi questa 
copia viene distrutta all'uscita della funzione. O restituisci D, oppure 
passi la variabile D per riferimento, invece che per valore.
E.


Salve,
Non è facile individuare la causa. Si dovrebbe cercare di ridurre la
quetione a poche righe di codice che riproducono il problema (un test
case).
Quello che mi viene in mente, da una lettura veloce, è che il valore
'uno.M' fornito liberamente dall'utente, viene usato per popolare D:
  D.push_back((( M/2 ) * (float) sin(2*PI*fzero*i))  + ( M/2 ));
questo valore di D, '(( M/2 ) * (float) sin(2*PI*fzero*i))  + ( M/
2 )', si usa dunque per accedere agli elementi di 'x':
  y.push_back(x[i] + g*x[(int)(i-D[i])]);
Questo valore potrebbe diventare negativo? Quale garanzia abbiamo che
l'indice in x 'i-D[i]'  sia limitato all'intervallo [0, numero
campioni in soundIN.txt - 1].
Oltre a provare a rintracciare questi valori durante l'esecuzione del
programma (usando il debugger), si dovrebbe cercare di ristrutturare
il vodice per assicurarsi che i valori degli indici negli arrary siano
validi indipendentamente da input esterni (input da parte dell'utente,
input da file), e che lo stato dell'oggetto di del tipo 'Effetto' sia
valido aldifuori dell'ordine nel quale si invocano i metodi della
classe (attualmente il vettore 'x' è popolato esternamente,
'Effetto::modulazione' e 'Effetto::mod' devono essere invocati prima
di 'Effetto::vibrato', ecc).
Sarebbe anche meglio non passare i valori membri ai metodi dello
stesso oggetto.
Se ha del tempo, si dovrebbe rafforzare le sue nozioni basi C++ e di
programmazione ad oggetti con dei buoni libri (
http://rudbek.com/
books.html).
Spero di esserla stato di aiuto, e in bocca al lupo.