Posizione librerie Visual C++
0
voti
[21] Re: Posizione librerie Visual C++
Ho studiato per bene il passaggio per valore e per riferimento(in realtà avevo già letto di cosa si trattava ma la cosa che mi risultava strana era che nella chiamata si passasse qualcosa che non era stata inizializzata). Ora rileggo con attenzione la tua risposta in modo da avere le idee più chiare. Intanto ti ringrazio per la pazienza e per la gentilezza.
-
dimaios
30,2k 7 10 12 - G.Master EY

- Messaggi: 3381
- Iscritto il: 24 ago 2010, 14:12
- Località: Behind the scenes
0
voti
[22] Re: Posizione librerie Visual C++
lellus ha scritto: ...ma la cosa che mi risultava strana era che nella chiamata si passasse qualcosa che non era stata inizializzata
Ottimo.
. Questo è un punto importante.
Anche se si dichiara il puntatore dell'oggetto in una classe e poi si delega la sua generazione ad un altro oggetto non è buona cosa non inizializzare il puntatore, anzi è uno degli errori più classici.
Nel C++ 98 si inizializzava con il valore "0" oppure a seconda delle definizioni nei vari compilatori trovavi cose tipo "NULL" oppure "null" o altro.
Finalmente nel C++ 11 questa variazione sul tema non esiste più visto che è stato introdotto il concetto di nullptr che finalmente non lascia spazio ad equivoci.
Come potrai leggere in questo thread anche il padre del C++ Bjarne Stroustrup concorda nel suo utilizzo.
Ingegneria : alternativa intelligente alla droga.
0
voti
[23] Re: Posizione librerie Visual C++
Continuo ad assillarvi con nuove domande
Ho preso ulteriore dimestichezza con il linguaggio e mi è stato chiesto di instanziare un oggetto della classe CMRBSysDecoder con il seguente costruttore:
Il file relativo alla matrice G da passare come primo parametro l'ho messo tra i file risorse in Visual Studio. Tra le risorse c'è anche il file .ini in cui una riga recita:
la stringa 16.12.listGmat.txt è stata memorizzata nel campo Value di una variabile kvGmat di tipo KeyString dove keyString è la seguente struct:
KeyString kvGmat è a sua volta un membro della struct SimParameters. Successivamente nel programma viene inizializzato un puntatore fSimPars a SimParameters in modo da poter scrivere:
Fin qui tutto ok perché ho usato il debug e verificato le variabili.
La parte di codice che ho scritto per istanziare il decoder e passare il file è:
Mi da un errore su fopen che recita: error C2664: 'fopen': impossibile convertire il parametro 2 da 'char' a 'const char *'
1> La conversione da tipo integrale a tipo puntatore richiede reinterpret_cast, cast di tipo C o cast di tipo funzione
Non capisco cosa sbaglio e cosa dovrei correggere. Sicuramente ci saranno diversi errori e spero mi possiate aiutare a venirne a capo. Grazie
Codice: Seleziona tutto
CMRBSysDecoder::CMRBSysDecoder(FILE *Gmatfile,
int max_MRB_iterations,
int *CodeDimension,
int order_input,
double threshold,
int TEP_file_flag,
char *TEP_file_name,
int min_dist)
Il file relativo alla matrice G da passare come primo parametro l'ho messo tra i file risorse in Visual Studio. Tra le risorse c'è anche il file .ini in cui una riga recita:
Codice: Seleziona tutto
Matrice-G = 16.12.listGmat.txt
la stringa 16.12.listGmat.txt è stata memorizzata nel campo Value di una variabile kvGmat di tipo KeyString dove keyString è la seguente struct:
Codice: Seleziona tutto
struct KeyString {[code][/code]
char *Key;
char *Value;
};
KeyString kvGmat è a sua volta un membro della struct SimParameters. Successivamente nel programma viene inizializzato un puntatore fSimPars a SimParameters in modo da poter scrivere:
Codice: Seleziona tutto
fSimPars->kvGmat.Value
Fin qui tutto ok perché ho usato il debug e verificato le variabili.
La parte di codice che ho scritto per istanziare il decoder e passare il file è:
Codice: Seleziona tutto
FILE *Gmatrix;
char *fgmat;
fgmat = new char[32];
strcpy(fgmat,fSimPars->kvGmat.Value);
Gmatrix = fopen(fgmat,'r');
*dpmrbdecoder = new CMRBSysDecoder(Gmatrix,
(fSimPars->MRBmaxI).Value,
dimension,
(fSimPars->MRBOrder).Value,
(fSimPars->MRBThreshold).Value,
(fSimPars->TEP_orig).Value,
fSimPars->TEP_list_file.Value,
(fSimPars->MinDist).Value);
fclose(Gmatrix);
delete[] fgmat;
Mi da un errore su fopen che recita: error C2664: 'fopen': impossibile convertire il parametro 2 da 'char' a 'const char *'
1> La conversione da tipo integrale a tipo puntatore richiede reinterpret_cast, cast di tipo C o cast di tipo funzione
Non capisco cosa sbaglio e cosa dovrei correggere. Sicuramente ci saranno diversi errori e spero mi possiate aiutare a venirne a capo. Grazie
0
voti
[24] Re: Posizione librerie Visual C++
Usa "r" e non 'r'. Caratteri e stringhe non sono la stessa cosa :)
Guardati il prototipo di fopen per capire quali sono i tipi da usare o ascolta gli errori di compilazione
Guardati il prototipo di fopen per capire quali sono i tipi da usare o ascolta gli errori di compilazione
"640K ought to be enough for anybody" Bill Gates (?) 1981
Qualcosa non ha funzionato...
Lo sapete che l'arroganza in informatica si misura in nanodijkstra?
Qualcosa non ha funzionato...
Lo sapete che l'arroganza in informatica si misura in nanodijkstra?
-
dimaios
30,2k 7 10 12 - G.Master EY

- Messaggi: 3381
- Iscritto il: 24 ago 2010, 14:12
- Località: Behind the scenes
0
voti
[25] Re: Posizione librerie Visual C++
Ci sono diversi problemi di programmazione in quello che hai scritto.
1. L'oggetto CMRBSysDecoder dovrebbe essere istanziato tramite uno smart pointer e non un puntatore nudo. I puntatori nudi sono molto pericolosi e con i nuovi paradigmi di programmazione fondamentalmente vietati.
In particolare :
In questo modo sei sicuro di deallocarlo al momento giusto ( non serve la delete perché lo smart pointer sa quando farla e la esegue quando nessuno possiede più la risorsa ).
A parte la sintassi iniziale per l'allocazione dpmrbdecoder lo usi come un puntatore classico ( ma ha anche metodi interessanti per fare cose che per ora non ti servono ).
2. perché fai la open del file fuori dall'oggetto CMRBSysDecoder ?
Questa cosa è pericolosa perché se qualcosa va storto all'interno del costruttore scateni un'eccezione che non gestisci per cui non chiamerai mai
Passa il nome del file come parametro al costruttore di CMRBSysDecoder e lui farà tutto quello che serve all' interno.
Se programmi ad oggetti, la prima cosa da fare è capire quali sono le funzioni da assegnare ad una classe.
Se il caricamento della matrice è una competenza di CMRBSysDecoder allora l'oggetto deve essere in grado di farlo in modo autonomo.
3. Questo frammento di codice
... in C++ non si dovrebbe proprio scrivere.
Utilizza le std::string e tutto risulta più facile.
Cerca di non usare la sintassi C quando puoi impiegare oggetti della standard library per risolvere il problema.
4. Questa struttura ...
Sarebbe meglio
In questo modo eviti le new e le malloc che hanno il problema del rilascio della memoria in caso di interruzione anomala del programma.
Un programmatore C++ non utilizza neanche la struct ma preferisce per vari motivi una class.
5. La funzione dovrebbe essere corredata dagli indispensabili try catch altrimenti non è sicura e non riesci a fare un debug efficace.
6. In C++ si evitano i FILE e si usano gli stream.
Utilizzando gli stream se qualcosa va storto nella lettura lo stream viene deallocato automaticamente all'uscita dallo scope della funzione evitando leakage di memoria.
Poi ci sarebbero anche altre considerazioni ma per ora bastano queste per apportare le modifiche fondamentali al codice.
1. L'oggetto CMRBSysDecoder dovrebbe essere istanziato tramite uno smart pointer e non un puntatore nudo. I puntatori nudi sono molto pericolosi e con i nuovi paradigmi di programmazione fondamentalmente vietati.
In particolare :
Codice: Seleziona tutto
std::shared_ptr<CMRBSysDecoder> dpmrbdecoder = std::make_shared( ..... constructor args ..... );
In questo modo sei sicuro di deallocarlo al momento giusto ( non serve la delete perché lo smart pointer sa quando farla e la esegue quando nessuno possiede più la risorsa ).
A parte la sintassi iniziale per l'allocazione dpmrbdecoder lo usi come un puntatore classico ( ma ha anche metodi interessanti per fare cose che per ora non ti servono ).
2. perché fai la open del file fuori dall'oggetto CMRBSysDecoder ?
Codice: Seleziona tutto
Gmatrix = fopen(fgmat,'r');Questa cosa è pericolosa perché se qualcosa va storto all'interno del costruttore scateni un'eccezione che non gestisci per cui non chiamerai mai
Codice: Seleziona tutto
fclose(Gmatrix);Passa il nome del file come parametro al costruttore di CMRBSysDecoder e lui farà tutto quello che serve all' interno.
Se programmi ad oggetti, la prima cosa da fare è capire quali sono le funzioni da assegnare ad una classe.
Se il caricamento della matrice è una competenza di CMRBSysDecoder allora l'oggetto deve essere in grado di farlo in modo autonomo.
3. Questo frammento di codice
Codice: Seleziona tutto
char *fgmat;
fgmat = new char[32];
strcpy(fgmat,fSimPars->kvGmat.Value);
... in C++ non si dovrebbe proprio scrivere.
Utilizza le std::string e tutto risulta più facile.
Cerca di non usare la sintassi C quando puoi impiegare oggetti della standard library per risolvere il problema.
4. Questa struttura ...
Codice: Seleziona tutto
struct KeyString {
char *Key;
char *Value;
};Sarebbe meglio
Codice: Seleziona tutto
struct KeyString {
std::string key ;
std::string value ;
};In questo modo eviti le new e le malloc che hanno il problema del rilascio della memoria in caso di interruzione anomala del programma.
Un programmatore C++ non utilizza neanche la struct ma preferisce per vari motivi una class.
5. La funzione dovrebbe essere corredata dagli indispensabili try catch altrimenti non è sicura e non riesci a fare un debug efficace.
Codice: Seleziona tutto
bool functionName( params )
{
try{
....
//Scrivi il tuo codice qui ....
....
return true ;
}
catch( std::exception& exc ){
//Se viene generata un'eccezione ....
cout << "Exception : " << exc.what() << std::endl;
return false ;
}
}
6. In C++ si evitano i FILE e si usano gli stream.
Utilizzando gli stream se qualcosa va storto nella lettura lo stream viene deallocato automaticamente all'uscita dallo scope della funzione evitando leakage di memoria.
Poi ci sarebbero anche altre considerazioni ma per ora bastano queste per apportare le modifiche fondamentali al codice.
Ingegneria : alternativa intelligente alla droga.
0
voti
[26] Re: Posizione librerie Visual C++
Grazie delle risposte. Facevo l'errore banale di scrivere 'r' invece di "r". Ho corretto e compila ma genera la seguente eccezione che non riesco a capire da dove possa provenire:
Eccezione non gestita di tipo 'System.AccessViolationException' in SimulazioneASPC.exe
Informazioni aggiuntive: Tentativo di lettura o scrittura della memoria protetta. Spesso questa condizione indica che altre parti della memoria sono danneggiate.
Lo stesso errore lo dava con la strcat nel seguente codice:
Per quanto riguarda il codice qui sotto, sbaglio o dichiara una matrice in cui ogni riga punta ad un array di interi?
Grazie ancora e scusate per le domande sicuramente banali.
Eccezione non gestita di tipo 'System.AccessViolationException' in SimulazioneASPC.exe
Informazioni aggiuntive: Tentativo di lettura o scrittura della memoria protetta. Spesso questa condizione indica che altre parti della memoria sono danneggiate.
Lo stesso errore lo dava con la strcat nel seguente codice:
Codice: Seleziona tutto
FileNames[FT_INI] = FNAME_INIT;
sprintf(FileNames[FT_Rescue], "%s%s", RESCUE_OUT_DIR, RESCUE_FNAME);
sprintf(FileNames[FT_QuantLawMsg], "%s%s", QUANT_OUT_DIR, QUANT_MSG_FNAME);
sprintf(FileNames[FT_QuantLawSig], "%s%s", QUANT_OUT_DIR, QUANT_SIG_FNAME);
sprintf(FileNames[FT_HDec], "%s%s", HDEC_OUT_DIR, HDEC_FNAME);
sprintf(FileNames[FT_RndState_Source], "%s%s", RANDSTATE_OUT_DIR, RNS_SOURCE_FNAME);
sprintf(FileNames[FT_RndState_Channel], "%s%s", RANDSTATE_OUT_DIR, RNS_CHANNEL_FNAME);
sprintf(FileNames[FT_RndState_Puncturer], "%s%s", RANDSTATE_OUT_DIR, RNS_PUNCTURER_FNAME);
/*
FileNames[FT_Rescue] = strcat(RESCUE_OUT_DIR, RESCUE_FNAME);
FileNames[FT_QuantLawMsg] = strcat(QUANT_OUT_DIR, QUANT_MSG_FNAME);
FileNames[FT_QuantLawSig] = strcat(QUANT_OUT_DIR, QUANT_SIG_FNAME);
FileNames[FT_HDec] = strcat(HDEC_OUT_DIR, HDEC_FNAME);
FileNames[FT_RndState_Source] = strcat(RANDSTATE_OUT_DIR, RNS_SOURCE_FNAME);
FileNames[FT_RndState_Channel] = strcat(RANDSTATE_OUT_DIR, RNS_CHANNEL_FNAME);
FileNames[FT_RndState_Puncturer] = strcat(RANDSTATE_OUT_DIR, RNS_PUNCTURER_FNAME);
*/
Per quanto riguarda il codice qui sotto, sbaglio o dichiara una matrice in cui ogni riga punta ad un array di interi?
Codice: Seleziona tutto
fCodeLen = CodeDimension[0];
fCodeDim = CodeDimension[1];
fCodeRed = fCodeLen - fCodeDim;
Gmat = (int**) malloc (sizeof(int*)*fCodeDim); //array di puntatori ad intero
for (i=0;i<fCodeDim;i++){
Gmat[i] = (int*) malloc (sizeof(int)*fCodeLen);
if (Gmat[i]==NULL){
//printf("\n Error: No memory available for generator matrix to reduce in echelon form\n");
exit(0);
}
}
Grazie ancora e scusate per le domande sicuramente banali.
0
voti
[27] Re: Posizione librerie Visual C++
Come prima e molto sensata modifica vorrei far aprire il file all'interno del costruttore dato che c'è già una sua funzione interna che si occupa di chiuder il file dopo aver inizializzato la matrice. In parole povere dovrei quindi passare invece del file un parametro tipo : fSimPars->kvGmat.Value che contiene la stringa con il nome del file e poi all'interno scrivere:
Purtroppo mi è stato richiesto di usare i file handler e quindi vorrei rispettare tale richiesta. In questo caso come li dovrei usare?? Cioè dopo aver scritto FILE *Gmatfile come apro il file a partire dal valore passato alla funzione(cioè fSimPars->kvGmat ).
Codice: Seleziona tutto
FILE *Gmatfile;
ecc...
Purtroppo mi è stato richiesto di usare i file handler e quindi vorrei rispettare tale richiesta. In questo caso come li dovrei usare?? Cioè dopo aver scritto FILE *Gmatfile come apro il file a partire dal valore passato alla funzione(cioè fSimPars->kvGmat ).

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)


