Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Übergabe eines vector-Objektes per Zeiger - Zeigerarithmetik

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
31.12.2015, 20:16 Uhr
Yadgar



Hi(gh)!

Ich will einen zweidimensionalen vector an einen Funktion übergeben, die Objekte vom selbst definierten Typ pixel an diesen vector anhängt:


C++:
bool loadTGA(vector<vector<pixel> >* img, string filename)
{

  ifstream Source;
  unsigned short idfield, width, height;
  // rgb triple;

  Source.open(filename.c_str(), ios::binary);
  if (!Source)
  {
    cerr << filename << " cannot be opened!\n";
    return false;
  }

  char ch;

  Source.get(ch); // reads in first byte: length of image identification field (0 - 255)
  idfield = (unsigned short)(unsigned char)ch;;

  Source.seekg(12, ios_base::beg); // file pointer is set to 12th byte
  Source.get(ch);
  width = (unsigned short)(unsigned char)ch;
  Source.get(ch);
  width += ((unsigned short)(unsigned char)ch)*256;
  Source.get(ch);
  height = (unsigned short)(unsigned char)ch;
  Source.get(ch);
  height += ((unsigned short)(unsigned char)ch)*256;



  unsigned int imgsize = width*height;
  unsigned int c; // counter

  img->resize(height);

  /* for (c=0; c<height; c++)
  {
    img[c].resize(width);
  } */


  c=0;
  pixel p;



  Source.seekg(18+idfield, ios_base::beg); // file pointer is set to first byte of pixel data
  while (Source.get(ch) && Source.tellg() <= 18+idfield+imgsize*3 )
  {
    switch (c%3)
    {
      case 0:
    p.set_blue((unsigned char)ch);
    // cout << (int)(unsigned char)p.get_blue() << endl;
        break;
      case 1:
    p.set_green((unsigned char)ch);
    // cout << (int)(unsigned char)p.get_green() << endl;
    break;
      case 2:
    p.set_red((unsigned char)ch);
    // cout << (int)(unsigned char)p.get_red() << endl;
    img+c/width->push_back(p);
    }

    c++;
  }
  return true;
}



Der vector enthält vector-Objekte, die wiederum aus pixel-Objekten bestehen; jedes pixel-Objekt ist drei Byte groß.

Für img+c/width->push_back(p); bekomme ich allerdings eine Fehlermeldung, und zwar:

[Error] base operand of '->' is not a pointer

Warum? Wenn img die Startadresse des gesamten vector-Objektes ist und c ein Zähler für die einzelnen eingelesenen Bytes (aus einer TGA-Grafikdatei), sollte doch jeder untergeordnete vector (entspricht einer Bildzeile) bei img+c/width beginnen...

Bis bald im Khyberspace!

Yadgar
--
Flagmaker - ein Programmier-Blog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
01.01.2016, 01:41 Uhr
ao

(Operator)


Das funktioniert so überhaupt nicht. Ein Vektor von Vektoren ist was anderes als ein 2dimensionales C-Style-Array.

Zuerst mal solltest du dir abgewöhnen, Pointer auf Objekte zu übergeben - dafür gibts in C++ die Referenz, das macht die Syntax einfacher. Deklarier die Funktion so:

bool loadTGA(vector<vector<pixel> >& img, const string & filename)

Dann: vector<vector<pixel>> ist ein Vektor von Vektor-Objekten, damit kann man keine Zeigerarithmetik machen. Zeigerarithmetik geht nur unter der Voraussetzung, dass das 2D-Objekt aus einem zusammenhängenden Speicherblock besteht, und das gilt hier nicht - jeder vector<pixel> hat seinen eigenen Datenbereich.

Berechne aus c den Zeilenindex und dann mach img[row].push_back (p).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
01.01.2016, 15:27 Uhr
Hans
Library Walker
(Operator)



Zitat von ao:
Ein Vektor von Vektoren ist was anderes als ein 2dimensionales C-Style-Array.


Die sind intern als verkettete Liste realisiert, oder?!
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.01.2016, 01:16 Uhr
Yadgar



Hi(gh)!


Zitat von ao:

bool loadTGA(vector<vector<pixel> >& img, const string & filename)

Dann: vector<vector<pixel>> ist ein Vektor von Vektor-Objekten, damit kann man keine Zeigerarithmetik machen. Zeigerarithmetik geht nur unter der Voraussetzung, dass das 2D-Objekt aus einem zusammenhängenden Speicherblock besteht, und das gilt hier nicht - jeder vector<pixel> hat seinen eigenen Datenbereich.

Berechne aus c den Zeilenindex und dann mach img[row].push_back (p).


Das hatte ich ursprünglich auch so gemacht - wunderte mich aber dann, dass z. B. das Invertieren eines Bildes merklich länger dauerte als etwa mit GIMP! Folglich kam ich auf die Idee, es mit Übergabe per Zeiger zu versuchen...

Aber danke für den Hinweis zu Vektoren - wieder etwas gelernt!

Bis bald im Khyberspace!

Yadgar
--
Flagmaker - ein Programmier-Blog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
05.01.2016, 10:01 Uhr
ao

(Operator)



Zitat von Yadgar:
Das hatte ich ursprünglich auch so gemacht - wunderte mich aber dann, dass z. B. das Invertieren eines Bildes merklich länger dauerte als etwa mit GIMP! Folglich kam ich auf die Idee, es mit Übergabe per Zeiger zu versuchen...

Die Übergabe per Zeiger ist merklich schneller als die Übergabe per Referenz? Das kann ich mir kaum vorstellen, denn die Referenz ist nur syntaktischer Zucker. Unter der Haube sind Zeiger und Referenz so gut wie dasselbe (bis auf den minimalen Unterschied, dass ein Zeiger 0 sein kann und eine Referenz immer auf ein gültiges Objekt verweisen muss). Hast du da gleichzeitig noch was anderes geändert?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
05.01.2016, 10:08 Uhr
ao

(Operator)



Zitat von Hans:
Zitat ao: "Ein Vektor von Vektoren ist was anderes als ein 2dimensionales C-Style-Array."
Die sind intern als verkettete Liste realisiert, oder?!

Glaub ich nicht. Mit einer verketteten Liste ist es nicht möglich, in konstanter Zeit auf beliebige Elemente zuzugreifen, und das ist eine Grundeigenschaft von vector.

Der Datenbereich von einem vector wird schon ein dynamisch alloziertes Array sein, aber eben nur ein 1D-Array für diesen einen vector und kein übergeordnetes 2D-Feld, auf dem mehrere vector-Objekte arbeiten.

Dieser Post wurde am 05.01.2016 um 10:09 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: