PDA

View Full Version : Problema puntatore con **


okay
12-04-2005, 17:00
ciao

Uso benissimo il ** per le stringhe ma non capisco dove mi perdo con gli int
premetto che dichiaro la variabile che non sà ancora quanti elementi conterrà.

Ecco cosa faccio:
//Dichiarazione
CSound **m_pSound;

//Inizializzazione NumeroFile parte che è = 1
m_pSound = (DllCSound ** )malloc ( sizeof (DllCSound *)* NumeroFile);

m_pSound[NumeroFile] = new CSound();
m_pSound[NumeroFile]->InitialiseForMP3();
m_pSound[NumeroFile]->LoadSound(NomeFile);

//Qui tutto è OK
C'è qualcosa che notate che non quadra in questa inizializzazione????
perchè a me funziona ma quando passo questa funzione mi da errore:
nBrano=1;
Traccia=0;
Sound(nBrano, Traccia);

Sto un pò nel pallone, non è che sbaglio a passare nBrano che è un int puro invece dovrei passare un puntatore????????
mi stà venedo qualche dubbio..............

ilsensine
12-04-2005, 17:04
//Dichiarazione
CSound **m_pSound;

//Inizializzazione NumeroFile parte che è = 1
m_pSound = (DllCSound ** )malloc ( sizeof (DllCSound *)* NumeroFile);

m_pSound[NumeroFile] = new CSound();
m_pSound[NumeroFile]->InitialiseForMP3();
m_pSound[NumeroFile]->LoadSound(NomeFile);

//Qui tutto è OK
C'è qualcosa che notate che non quadra in questa inizializzazione????
Se NumeroFile è la stessa variabile sia nella malloc che nell'array seguente, è chiaramente un overflow.

perchè a me funziona ma quando passo questa funzione mi da errore:
nBrano=1;
Traccia=0;
Sound(nBrano, Traccia);

Sto un pò nel pallone, non è che sbaglio a passare nBrano che è un int puro invece dovrei passare un puntatore????????
mi stà venedo qualche dubbio..............
Tradotto?

okay
12-04-2005, 18:42
NumeroFile è il n. del file da mettere nella pila e se voglio suonare il file sonoro n. 1 passo nBrano=1 oppure il secondo file sonoro passo nBrano=2.

......... comunque non ho capito cosa intendi per seguente............

Credo che l'inizializzazione sia sbagliata anche se mi linka senza errori.
Sono capace a farlo con le stringhe infatti per le stringhe:

//Dichiarazione
char **SoundLista=NULL;
//Inizializzazione
SoundLista = (char ** )malloc ( sizeof (char *) * NumeroFile);
SoundLista[NumeroFile] = (char *) malloc (strlen(NomeFile)+1);
strcpy(SoundLista[NumeroFile],NomeFile);

questo è perfetto ma riadattandolo al quesito sopra ho un'errore

cionci
12-04-2005, 19:46
Anche quello sopra è sbagliato...devi inizializzare un elemento per ogni file quindi, il codice sotto:

SoundLista[cont] = (char *) malloc (strlen(NomeFile)+1);
strcpy(SoundLista[cont],NomeFile);
++cont;

lo dovrai richiamare quando avrai a disposizione un nuovo nome di file da mettere nella lista di file...

Per tenere gli oggetti CSound non hai bisogno di un puntatore a puntatore (**), ma solo di un vettore...

//Dichiarazione
CSound *m_pSound;

//Inizializzazione NumeroFile parte che è = 1
m_pSound = (DllCSound *)malloc ( sizeof (DllCSound) * NumeroFile);
cont = 0;

A questo punto inserisci i vari CSound nel

m_pSound[cont] = new CSound();
m_pSound[cont]->InitialiseForMP3();
m_pSound[cont]->LoadSound(NomeFile);
cont++;

Ovviamente il massimo numero di elementi che in entrambi i casi potrai inserire è pari a NumeroFile...

Se la tua intenzione è quella di modificare il numero di elementi insiribili nei vettori a run time...cioè variare NumeroFile a runtime allora devi usare realloc...

okay
13-04-2005, 15:51
Abbi pazienza cionci......... ti spigo cosa sto facendo:
Con un ciclo while controllo quanti file .mp3 sono nella directory.
Io o l'utente non sà quanti files ci sono nella directory per questo motivo inizializzo:
char **SoundLista=NULL; //non sò quanti files ci saranno in dir e
CSound **m_pSound=NULL;//come sopra

Li leggo uno ad uno e inizializzo a runtime:

Ti faccio il tutto in pseudo codice:

//Dichiarazione
char **SoundLista=NULL;
CSound **m_pSound=NULL;

int NumeroFile=1;
do
{

SoundLista = (char ** )malloc ( sizeof (char *) * NumeroFile);
SoundLista[NumeroFile] = (char *) malloc (strlen(NomeFile)+1);
strcpy(SoundLista[NumeroFile],NomeFile);

//Questa sotto non sò se è giusta me la linka ma poi ho un errore come di
//di puntatore nella chiamata di funzione Sound(nBrano, Traccia);
m_pSound = (DllCSound ** )malloc ( sizeof (DllCSound *)* NumeroFile);

//poi faccio
m_pSound[cont] = new CSound();
m_pSound[cont]->InitialiseForMP3();
m_pSound[cont]->LoadSound(NomeFile);

NumeroFile++;

}while (FindNextFileW(hFindFileW, &finddata));

-------------------------

se il codice sopra lo inizializzo con doppio ** e anche nella malloc con doppio ** tutto è linkato e funziona ma alla chiamata ho un errore di puntatore
che ne pensi??????

okay
13-04-2005, 16:09
Cionci ho fatto come tu hai detto sopra con un solo + per il vettore ma...................

su questa chiamata:
g_pGioco->m_pSound[nBrano]->Play(Traccia); //Play(n); traccia
e altre... ho questo errore:
c:\Documents and Settings\Valter\Desktop\DLL\Dll.cpp(140): error C2227: left of '->Play' must point to class/struct/union
type is 'DllCSound'
did you intend to use '.' instead?


Forse in questo modo sopra come da te detto devo effettuare la chiamata tramite puntatore.
--------------------------

Come facevo prima invece:

DllCSound *m_pSound[99];
char SoundLista[99][MAX_PATH];
//diciamo che in dir ho 8 file.mp3
m_pSound[NumeroFile] = new DllCSound();
m_pSound[NumeroFile]->InitialiseForMP3();
m_pSound[NumeroFile]->LoadSound(SoundLista[NumeroFile]);
NumeroFile++;
//fine while
g_pGioco->m_pSound[nBrano]->Play(Traccia);

tutto perfetto.......................

nel modo sopra cosa non và?????????????

cionci
13-04-2005, 17:07
Avevo sbagliato anche io sopra ;)
Deve essere CSound **m_pSound...

//Dichiarazione
char **SoundLista=NULL;
CSound **m_pSound=NULL;

int NumeroFile=1;
do
{

SoundLista = (char ** )malloc ( sizeof (char *) * NumeroFile);
SoundLista[NumeroFile] = (char *) malloc (strlen(NomeFile)+1);
strcpy(SoundLista[NumeroFile],NomeFile);

//Questa sotto non sò se è giusta me la linka ma poi ho un errore come di
//di puntatore nella chiamata di funzione Sound(nBrano, Traccia);
m_pSound = (DllCSound ** )malloc ( sizeof (DllCSound *)* NumeroFile);

//poi faccio
m_pSound[cont] = new CSound();
m_pSound[cont]->InitialiseForMP3();
m_pSound[cont]->LoadSound(NomeFile);

NumeroFile++;

}while (FindNextFileW(hFindFileW, &finddata));

Il problema del codice è diverso...

SoundLista = (char ** )malloc ( sizeof (char *) * NumeroFile);

Se fai questa allocazione con NumerFile == 1 creerai un vettore con un solo puntatore...

E tutte le volte che andrai a passare su quella sitruzione sul ciclo perderai il puntatore al vettore precedente (memory leak) ed il contenuto del vettore precedentemente assegnato...

Ci sono due modi di operare in questi casi o si usano le liste o si usa realloc (che presuppone un reallozione di tutte il vettore e la copia dei dati contenuti in quello vecchio in quello nuovo)... Se volessi usare la libreria standard C++ si fa tutto con un vector...

Quindi fai una lista... E' il modo più semplice... Te la scrivo in C++ visto che stai usando quello...

struct sound_file {
char *filename;
CSound *sound;
};

struct sound_list {
sound_file sound_data;
sound_list *next;
};

int NumeroFile = 1;
sound_list *lista = new sound_list;
lista->next = NULL;

HANDLE hFindFileW = FindFirstFile("*.mp3", &finddata);

lista->sound_data.filename = new char[strlen(finddata.cFileName)+1];
strcpy(finddata.cFileName, lista->sound_data.filename);

lista->sound_data.sound = new CSound();
lista->sound_data.sound->InitialiseForMP3();
lista->sound_data.sound->LoadSound(lista->sound_data.filename);

sound_list *cur = lista;

while(FindNextFileW(hFindFileW, &finddata))
{
cur = cur->next = new sound_list;
cur->next = NULL;
cur->sound_data.filename = new char[strlen(finddata.cFileName)+1];
strcpy(finddata.cFileName, cur->sound_data.filename);

cur->sound_data.sound = new CSound();
cur->sound_data.sound->InitialiseForMP3();
cur->sound_data.sound->LoadSound(cur->sound_data.filename);

NumeroFile++;
}

A questo punto hai tutti i dati memorizzati in una lista...se li vuoi avere a disposizione in un vettore basta spostarli in un vettore...

sound_file *m_pSound = new sound_file[NumeroFile];
cur = lista;
int i = 0;
while(cur)
{
m_pSound[i++] = cur->sound_data;
sound_list *tmp = cur->next;
delete cur;
cur = tmp;
}


....
....

g_pGioco->m_pSound[nBrano].sound->Play(Traccia);

Ora hai tutti i tuoi file all'interno di un vettore di grandezza NumeroFile...

Sappi che con i vector della libreria standard C++ si vaceva in un solo passaggio...

okay
13-04-2005, 18:00
Grazie cionci sei stato moolto chiaro:

ora ci provo e ti faccio sapere solo una cosa:
Ho notato che il ciclo do non và bene e questo l'ho notato casualmente (per fortuna)
se cerco con "*.*" esce sempre dal ciclo allora mi sono aiutato con un ciclo for se 0 ecc,ecc, passo i rispttivi ".mp3" ".wav" ".mid"
Il problema è che ho notato che se metto in dir un solo file per esempio file.mp3
mi trova 3 volte file.mp3 con il contatore NumeroFile=3 alla fine anche se la dir quando cerca è =1 finisce con .wav. Il problema te l'ho scritto nel commento che puoi vedere in basso dopo il do.....................

----------------- CODE----------------------------------
for(int cerca=0; cerca<3; cerca++){

CHAR strSoundPath[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, strSoundPath);
if(cerca==0)
strcat(strSoundPath, "\\Okisound\\*.mp3");
if(cerca==1)
strcat(strSoundPath, "\\Okisound\\*.wav");
if(cerca==2)
strcat(strSoundPath, "\\Okisound\\*.mid");

WCHAR wstrSoundPath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, strSoundPath, -1, wstrSoundPath, MAX_PATH);

WIN32_FIND_DATAW finddata;
HANDLE hFindFileW = FindFirstFileW(wstrSoundPath, &finddata);


do
{

//Ecco quando la dir sta a cerca=1 e finisce in .wav la variabile sotto
//finddata.cFileName vale sempre File.mp3
//anche quando cerca=2 e la dir finisce con .mid
//la variabile finddata.cFileName è uguale all'unico file in dir appunto File.mp3
//per questo motivo mi calcola che ho 3 volte File.mp3
//come posso ovviare a questo intanto ci stà lavorando
int a = lstrlenW(finddata.cFileName)+1;

char *NomeFile = new char[a];

WideCharToMultiByte(CP_ACP, 0, finddata.cFileName, -1, NomeFile, a, NULL, NULL);
strcpy(SoundLista[NumeroFile], NomeFile);

}while (FindNextFileW(hFindFileW, &finddata));


-------- END CODE ---------------------------------------

okay
13-04-2005, 18:12
Per l'ultima domanda ho risolto così:

if(cerca==0 && tolower(NomeFile[bx-1])==tolower('3') || cerca==0 && toupper(NomeFile[bx-1])==toupper('3'))
{
NumeroFile++;
}
if(cerca==1 && tolower(NomeFile[bx-1])==tolower('v') || cerca==0 && toupper(NomeFile[bx-1])==toupper('V'))
{
NumeroFile++;
}
if(cerca==2 && tolower(NomeFile[bx-1])==tolower('d') || cerca==0 && toupper(NomeFile[bx-1])==toupper('d'))
{
NumeroFile++;
}

facendo un controllo sull'ultimo carattere confrontando con && la int cerca

grazie ora provo per quell'altra cosa a dopo

okay
13-04-2005, 19:36
struct sound_file {
char *filename;
CSound *sound;
};

struct sound_list {
sound_file sound_data;
sound_list *next;
};


Ho un problema non riesco a implementare il codice sopra. l
Le struct nelle mie classi dove le metto?? non posso usarle Globali devono essere legate a CSound


//Gioco.h
CGioco
{
public:

CSound *m_pSound;

CGioco();
virtual ~CGioco();

protected:

private:

};


//Gioco.cpp
CGioco::CGioco()
{
m_pSound=NULL;
}

CGioco::~CGioco()
{

}


Stessa cosa per CSound
come implemento le tue struct nella mia classe
io ho sempre adoperato le struct come globali??

cionci
13-04-2005, 19:39
Definiscile nel .h di CSound...