PDA

Visualizza la versione completa : [C++] Allocazione dinamica e passaggio per riferimento.


adrycast
14-11-2010, 12:10
Salve ragazzi.
E' la prima volta che scrivo in questo forum quindi siate gentili e comprensivi :)

Vado subito al dunque: sono scritto ad Ingegneria Informatica e quest'anno abbiamo iniziato a lavorare in C++ ad un livello un pò più avanzato e quindi con allocazione dinamica, ADT e (a breve) classi, oggetti e compagnia bella.
Il problema è che al primo corso riguardante il C abbiamo trattato pochissimo i puntatori e di consegenza quest'anno mi ritrovo con 'ste variabili "strane" anche se non del tutto sconosciute.
Ora sto svolgendo un problema che mi chiede di creare un record Prodotto (staticamente) e di puntarlo con un puntatore e creare le varie funzioni per inserimento e cancellazione passando per riferimento questo puntatore al record. Fin qui è abbastanza semplice dato che, per non creare confusione, utilizzo il typedef e sostanzialmente mi levo quell'asterisco davanti...

Tutto questo però è per UN SOLO prodotto, queste funzioni vanno poi utilizzate per la creazione di un magazzino che va fatto con un vettore allocato dinamicamente contenente N puntatori che puntano al puntatore (descritto sopra) che a sua volta punti al record Prodotto.
Sostanzialmente è come creare una matrice allocata dinamicamente...

Allora ho creato due header, uno per le funzioni dedicate al singolo prodotto ed uno per le funzioni dedicate al magazzino.
In prodotto.h creo il record Prodotto e dopo metto "typedef Prodotto * prod", quindi alle funzioni passo valori di tipo "prod &"
In magazzino.h metto invece "typedef prod * mag" e alle funzioni passo valori di tipo "mag &".

Ora: il compilatore non dà errori, l'eseguibile viene creato...ma eseguo e quando entra nella funzione per inizializzare il magazzino (dove chiedo quanti prodotti verranno inseriti) tutto ok, appena iniziano le funzioni dedicate al prodotto mi si inceppa tutto (sostanzialmente il programma chiede di inserire il codice prodotto, lo inserisco, premo invio e si incasina)...

Ah ultima cosa, all'università la prof utilizza Dev-C++, io però, quasi sempre preferisco utilizzare Xcode che mi sembra un pò più comodo (crea gli header da solo, quando definisco un tipo con typedef, me lo colora in modo da distinguerlo ecc ecc). Non so se cambia qualcosa..

MacApp
14-11-2010, 13:36
Originariamente inviato da adrycast
mi si inceppa tutto (sostanzialmente il programma chiede di inserire il codice prodotto, lo inserisco, premo invio e si incasina)...

E' un po' difficile provare ad aiutarti per risolvere il tuo problema con così pochi indizi non credi?
;-)
cmq se proprio ti da fastidio l'asterisco * meglio fare:


typedef Prodotto * ProdottoPtr;



Originariamente inviato da adrycast
Ah ultima cosa, all'università la prof utilizza Dev-C++, io però, quasi sempre preferisco utilizzare Xcode che mi sembra un pò più comodo (crea gli header da solo, quando definisco un tipo con typedef, me lo colora in modo da distinguerlo ecc ecc). Non so se cambia qualcosa..
Dev-C++ è obsoleto, Xcode è ottimo.
Se vuoi capire meglio cosa avviene "sotto", non escludere di provare a compilare direttamente da linea di comando utilizzando gcc/g++.

adrycast
14-11-2010, 14:42
Originariamente inviato da MacApp
E' un po' difficile provare ad aiutarti per risolvere il tuo problema con così pochi indizi non credi?
;-)


Eh ci avevo pensato però ho pensato anche che pubblicare tutto il codice era esagerato :P
vabbe comunque mo posto le parti incriminate:

questo è prodotto.h


#include <iostream>
#include <cstdlib>

using namespace std;

const int DIM=50;
typedef char stringa [DIM];
typedef struct Prodotto {
stringa Cod;
stringa Descr;
int Qta;
};

typedef Prodotto * prod;

void Insert_Prod (prod &);
void Delete_Prod (prod);


Questa è la funzione del prodotto che acquisisce il codice, la descrizione e la quantità


void Insert_Prod (prod & punt) {

cout<<"\n Codice prodotto: ";
cin.ignore();
cin.getline(punt->Cod,DIM+1);
cout<<"\n Descrizione prodotto: ";
cin.ignore();
cin.getline(punt->Descr,DIM+1);
cout<<"\n Quantita' prodotto: ";
cin>>punt->Qta;

}


Mentre le due che seguono sono rispettivamente il file header riguardante il vettore (magazzino.h) e la funzione che alloca ed inizializza il vettore.



#include "prodotto.h"

typedef prod * mag;

void Create_Mag (mag &, int &);
void Search_Mag (const mag, int);
void Delete_mag (mag &, int);




void Create_Mag (mag & v, int & n) {

cout<<"\n Numero di prodotti da inserire: ";
cin>>n;
v= new prod [n];
for (int i=0;i<n;i++){

cout<<"\n Prodotto "<<i;
Insert_Prod (v[i]);
}
}



Poi questo è il main che ho fatto, è ovviamente temporaneo giusto per controllare che l'allocazione del vettore riesca.


#include "magazzino.h"

int main () {

mag v;
int n;
Create_Mag(v,n);

return 0;
}


Come dicevo prima il programma arriva a farmi inserire il codice prodotto del primo elemento, dopodichè va in tilt e compaiono queste scritte



[Session started at 2010-11-14 14:34:02 +0100.]
Loading program into debugger…
GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct 2 04:07:49 UTC 2007)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
Program loaded.
sharedlibrary apply-load-rules all
Attaching to program: `/Users/adry_cast/Desktop/Progetti C++/Magazzino_dinamico/build/Debug/Magazzino_dinamico', process 1206.
warning: Could not find malloc init callback function.
Make sure malloc is initialized before calling functions.
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
unable to read unknown load command 0x80000022
(gdb)



La prossima volta posto tutto dall'inizio :D



Originariamente inviato da MacApp
Dev-C++ è obsoleto, Xcode è ottimo.
Se vuoi capire meglio cosa avviene "sotto", non escludere di provare a compilare direttamente da linea di comando utilizzando gcc/g++.


Immaginavo che fosse un pò obsoletuccio...
Per quel che riguarda il capire meglio, in realtà io con il dev-c++ mi faccio anche il makefile però con xcode ancora non ho provato...

MacApp
14-11-2010, 17:07
in Create_Mag gli elementi di v (che sono dei puntatori a Prodotto) non sono stati allocati. Fai cosi':


void Create_Mag (mag & v, int & n) {

cout<<"\n Numero di prodotti da inserire: ";
cin>>n;
v= new prod [n];
for (int i=0;i<n;i++){

cout<<"\n Prodotto "<<i;
v[i]= new Prodotto;
Insert_Prod (v[i]);
}
}

adrycast
14-11-2010, 17:49
Originariamente inviato da MacApp
in Create_Mag gli elementi di v (che sono dei puntatori a Prodotto) non sono stati allocati. Fai cosi':


void Create_Mag (mag & v, int & n) {

cout<<"\n Numero di prodotti da inserire: ";
cin>>n;
v= new prod [n];
for (int i=0;i<n;i++){

cout<<"\n Prodotto "<<i;
v[i]= new Prodotto;
Insert_Prod (v[i]);
}
}


Cavolo sono un demente :dhò:

Non ci avevo proprio pensato che poi, giustamente, ogni puntatore del vettore è di tipo Prodotto ma non alloca lo spazio per crearlo :P
Vabbè poi per renderlo maggiormente implementabile (che è quello che la prof cerca da noi) invece di mettere l'istruzione nella funzione che inizializza il vettore l'ho messa nella funzione del singolo prodotto



void Insert_Prod (prod & punt) {

punt= new Prodotto;
cout<<"\n Codice prodotto: ";
cin.ignore();
cin.getline(punt->Cod,DIM+1);
cout<<"\n Descrizione prodotto: ";
cin.ignore();
cin.getline(punt->Descr,DIM+1);
cout<<"\n Quantita' prodotto: ";
cin>>punt->Qta;

}


Grazie mille sei stato gentilissimo ;)

Loading