Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  c++ massiivi return märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
asjameez
Kreisi kasutaja
asjameez

liitunud: 10.12.2006




sõnum 18.04.2010 00:19:10 c++ massiivi return vasta tsitaadiga

GLfloat* Controls::GetVars() {
   GLfloat Vars[5] = {Pos_X, Pos_Y, Pos_Z, Rot_X, Rot_Y};
   return Vars;
}


Üleval olev koodijupp annab hoiatuse:
tsitaat:
warning: address of local variable ‘Vars’ returned


Mis ma valesti teen massiivi returnides? icon_rolleyes.gif
Kommentaarid: 63 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 61
tagasi üles
vaata kasutaja infot saada privaatsõnum
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 18.04.2010 10:41:58 vasta tsitaadiga

Sa tagastad aadressi funktsiooni stackis olevale muutjale, mis võidakse ülekirjutada tulevikus ning peale seda omavad su tagastatud massiivis elemendid suvalisi väärtusi.
Sa peaksid Vars muutujale eemaldama mälu new abil ja tagastama viitne eraldatud mälule.
c++:
  1. GLfloat *Controls::GetVars() {
  2.      GLfloat *Vars = new GLfloat[5];
  3.      Vars[0] = Pos_X;
  4.      /* jne ... */
  5.      return Vars;
  6. }
  7.  

_________________
ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
Kommentaarid: 34 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
asjameez
Kreisi kasutaja
asjameez

liitunud: 10.12.2006




sõnum 18.04.2010 11:49:20 vasta tsitaadiga

troglodyte, hoiatus kadus thumbs_up.gif
Kommentaarid: 63 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 61
tagasi üles
vaata kasutaja infot saada privaatsõnum
Supiplex
HV veteran
Supiplex

liitunud: 11.12.2002




sõnum 19.04.2010 11:20:40 vasta tsitaadiga

Ära unusta seda massiivi hiljem delete() abil ära kustutada.

Veidi küll hilinenud nõu, aga mugavam oleks lahendada massiiv STL objektina. Seda saab tagastada nagu suvalist kohalikku muutujat:

#include <array>

stl::array<GLfloat> Controls::GetVars() {
   stl::array<GLfloat> Vars;
   Vars.push_back(Pos_X);
   Vars.push_back(Pos_Y);
   Vars.push_back(Pos_Z);
   Vars.push_back(Rot_X);
   Vars.push_back(Rot_Y);
   return Vars;
}

_________________
The young lady had an unusual list,
Linked in part to a structural weakness.
She set no preconditions.
Kommentaarid: 38 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ho Ho
HV Guru
Ho Ho

liitunud: 16.02.2002




sõnum 19.04.2010 13:41:28 vasta tsitaadiga

Supiplex'i idee tehniliselt õige, kuid suts ebaefektiivne kuna toimub kogu vectori kopeerimine returni juures. See, et andmetüübid-namespaced veidi valed on ei ole antud hetkel väga oluline icon_smile.gif


Ise teeks tõenäoliselt hoopis sedasi, et looks tolle massiivi funktsiooniväliselt ning laseks ainult tollel funkstioonil too massiiv täita. Ehk siis umbes nii:
c++:
  1. #include <vector>
  2.  
  3. // Funkstiooni parameetriks on reference massiivile, reference on võrreldav pointeriga
  4. void getVars(std::vector<GLfloat>& array) {
  5.     // tühjendab massiivi ja teeb selle piisava suuruse peale
  6.     array.resize(5);
  7.  
  8.     // sisestab andmed masiivi
  9.     array[0]=Pos_X;
  10.     array[1]=Pos_Y;
  11.     array[2]=Pos_Z;
  12.     array[3]=Rot_X;
  13.     array[4]=Rot_X;
  14. }
  15.  
  16. int main(int argc, char* argv[]) {
  17.     std::vector<GLfloat> array;
  18.     getVars(array);
  19.     return 1;
  20. }

vältisin push_back'i kasutust kuna sel pole lihtsalt mõtet. Vektori suurus on ju algusest peale teada.

Üldjuhul tasub manuaalset mäluhaldust new/delete'ga vältida võimalikult palju ning kasutada standardteeke. Sellega minimeerid võimalikke bugide tekkimisi. Hetkel tööl on ~50k rea pikkune kood kus on kokku ~10 new/delete paari ning praktiliselt kõik nood tehakse ühekordselt vastavalt progammi käivitusel/sulgemisel icon_smile.gif

[edit]
Hm, jäi märkamata tõsiasi et tõenäoliselt on tegu ühe klassifunktsiooniga. Sel juhul teeksin hoopis umbes nii:
c++:
  1.  
  2. class Controls {
  3.     // hoiab parameetreid
  4.     std::vector<GLfloat> params;
  5. public:
  6.     // constructor
  7.     Controls() {
  8.         // parameetrite massiivi suurus paika, automaatselt täidetakse nullidega
  9.         params.resize(5);
  10.     }
  11.     // määrab parameetrid, vektori suurus on paika pandud juba constructoris
  12.     void setParams(GLfloat x, GLfloat y, GLfloat z, GLfloat rx, GLfloat  ry) {
  13.         params[0] = x;
  14.         params[1] = y;
  15.         params[2] = z;
  16.         params[3] = rx;
  17.         params[4] = ry;
  18.     }
  19.     // Tagastab reference parameetrite massiivile mida ei lubata muuta. Lõpus olev const on lihtsalt vihje kompilaatorile et selles funktsioonis ei muudeta klassi väärtusi
  20.     const std::vector<GLfloat>& getParams() const {
  21.         return params;
  22.     }
  23. };
  24.  
  25. // Hiljem koodis:
  26. Controls c;
  27. const vector<GLfloat>& params = c.getParams();

_________________
Teach a man to reason and he'll think for a lifetime
Common sense - so rare that it's a damn superpower
Vaadates paljude inimeste sõnavõtte siin ja mujal jääb üle ainult klassikuid tsiteerida - "I weep for humanity"
Kommentaarid: 106 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 86
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
Supiplex
HV veteran
Supiplex

liitunud: 11.12.2002




sõnum 19.04.2010 16:50:50 vasta tsitaadiga

Ho Ho kirjutas:
Supiplex'i idee tehniliselt õige, kuid suts ebaefektiivne kuna toimub kogu vectori kopeerimine returni juures.


Muide, seda vektorit ei kopeerita tagastamisel. Mõistlik kompilaator (näiteks gcc) jätab kopeerimise ära kui funktsioon tagastab ühe kindla lokaalse muutuja. Lisainfoks googelda näiteks "return value optimization".

Kompilaator on targem kui sa arvad icon_wink.gif Kuluta oma energiat nii, et endal oleks lihtsam kribada ja teistel lugeda.

tsitaat:
See, et andmetüübid-namespaced veidi valed on ei ole antud hetkel väga oluline icon_smile.gif


Mu projektis on kasutusel mikro-STL mille namespace on "ustl", mitte "std". Arva ära kui mitu korda ma olen end viimase paari kuu jooksul seaks vihastanud kui kirjutan std::string ja üritan veerand tundi aru saada miks see neetud kompilaator viriseb et ta sellist looma ei leia icon_biggrin.gif No pikapeale on tekkinud komme teistpidi kirjutada.

_________________
The young lady had an unusual list,
Linked in part to a structural weakness.
She set no preconditions.
Kommentaarid: 38 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ho Ho
HV Guru
Ho Ho

liitunud: 16.02.2002




sõnum 19.04.2010 16:53:35 vasta tsitaadiga

Supiplex kirjutas:
Mõistlik kompilaator (näiteks gcc) jätab kopeerimise ära kui funktsioon tagastab ühe kindla lokaalse muutuja
Võimalik, ju ma olen siis MSVC'ga ära "hellitatud" kui debugger iga sarnase liigutuse peale läbi copy-constructori käib.
_________________
Teach a man to reason and he'll think for a lifetime
Common sense - so rare that it's a damn superpower
Vaadates paljude inimeste sõnavõtte siin ja mujal jääb üle ainult klassikuid tsiteerida - "I weep for humanity"
Kommentaarid: 106 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 86
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
Supiplex
HV veteran
Supiplex

liitunud: 11.12.2002




sõnum 19.04.2010 20:05:54 vasta tsitaadiga

Ei, miks. VC oskab sedasama, aga tavaliselt jooksutad sa ju debuggerit optimeerimata koodi peal.
_________________
The young lady had an unusual list,
Linked in part to a structural weakness.
She set no preconditions.
Kommentaarid: 38 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  c++ massiivi return
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.