Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » STL Bug?

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
07.10.2005, 03:05 Uhr
Pablo
Supertux
(Operator)


Hi
ich hab etwas festgestellt:
ich bin sicher, dass ich alles richtig getan habe (an keiner Stelle verwende ich = new datentyp[...]; ) und deswegen denke ich, dass das ein STL Fehler ist, mal sehen.

Ich hab folgendes:


C++:
// pixel.hh

#ifndef CLASS_PIXEL_HH
#define CLASS_PIXEL_HH

#include <iostream>

class pixel
{
        private:
        
                int red;
                int green;
                int blue;

        public:
        
                pixel();
                pixel(int r, int g, int b);
                int get_red();
                int get_green();
                int get_blue();
                void set_red(int r);
                void set_green(int g);
                void set_blue(int b);

                void setValue(int r, int g, int b);
                void getValue(int &r, int &g, int &b);

                friend std::ostream &operator<<(std::ostream& os, pixel& p);
};

#endif

// ----------------------

// pixel.cc

#include "pixel.hh"

pixel::pixel()
{
        this->red = this->green = this->blue = 0;
}

pixel::pixel(int r, int g, int b)
{
        this->red = r;
        this->green = g;
        this->blue = b;
}

int pixel::get_red()
{
        return this->red;
}

int pixel::get_green()
{
        return this->green;
}

int pixel::get_blue()
{
        return this->blue;
}

void pixel::set_red(int r)
{
        this->red = r;
}

void pixel::set_green(int g)
{
        this->green = g;
}

void pixel::set_blue(int b)
{
        this->blue = b;
}

void pixel::setValue(int r, int g, int b)
{
        this->red = r;
        this->green = g;
        this->blue = b;
}

void pixel::getValue(int &r, int &g, int &b)
{
        r = this->red;
        g = this->green;
        b = this->blue;
}

std::ostream &operator<<(std::ostream& os, pixel& p)
{
        os << "rgb(" << p.get_red() << ", " << p.get_green()
           << ", " << p.get_blue() << ")" << std::flush;

        return os;
}




C++:
// binarypixel.hh


#ifndef CLASS_BINARY_PIXEL_HH
#define CLASS_BINARY_PIXEL_HH

#include "pixel.hh"

class binaryPixel : public pixel
{
        public:
                binaryPixel();
                binaryPixel(int r, int g, int b);
                
                void setBinValue(int r, int g, int b);
                void getBinValue(int &r, int &g, int &b);
};

#endif

// ------------------------

// binarypixel.cc

#include <cmath>

#include "binarypixel.hh"

binaryPixel::binaryPixel()
{
        ::pixel();
}

binaryPixel::binaryPixel(int r, int g, int b)
{
        this->setValue(r,g,b);
}

void binaryPixel::setBinValue(int r, int g, int b)
{
        int red, green, blue;

        this->getValue(red, green, blue);

        if(r==1 && !fmod(red, 2))
                set_red(++red);
        else if(!r && fmod(red, 2) == 1)
                set_red(--red);

        if(g==1 && !fmod(green, 2))
                set_green(++green);
        else if(!g && fmod(green, 2) == 1)
                set_green(--green);

        if(b==1 && !fmod(blue, 2))
                set_blue(++blue);
        else if(!b && fmod(blue, 2) == 1)
                set_blue(--blue);      
}

void binaryPixel::getBinValue(int &r, int &g, int &b)
{
        r = (int) fmod(this->get_red(), 2);
        g = (int) fmod(this->get_green(), 2);
        b = (int) fmod(this->get_blue(), 2);
}




C++:
// bild.hh

#ifndef TEMPLATE_BILD_H
#define TEMPLATE_BILD_H

#include <vector>
#include <iostream>

template<typename T>
class bild
{
        private:
                std::vector<T> pixels;
                                      
                int x_size, y_size; // important for resizing
        public:
                bild(); /* size 16x16 */
                bild(int x_size, int y_size);
                T *getPixel(int pos); // get pixel from 1D position position
                void resize(int x_size, int y_size); // do not interpolate.
                void printImage();              
};

template<typename T> bild<T>::bild()
{
        this->x_size = this->y_size = 10;
        this->pixels.resize(100);
}

template<typename T> bild<T>::bild(int x_size, int y_size)
{
        this->x_size = x_size;
        this->y_size = y_size;

        this->pixels.resize(x_size*y_size);
}

template<typename T> T *bild<T>::getPixel(int pos)
{
        // if pos is an invalid value, return the first element!
        if(pos < 0 || (pos > this->x_size * this->y_size - 1))
                return &this->pixels[0];

        return &this->pixels[pos];
}

template<typename T> void bild<T>::resize(int x_size, int y_size)
{
        // TODO: complete me
}

template<typename T> void bild<T>::printImage()
{
        int pos = 0;

        for(typename std::vector<T>::iterator pix = this->pixels.begin(); pix != this->pixels.end(); ++pix)
        {
                std::cout << *pix;

                if(pos++ % this->x_size)
                        std::cout << "\n";
                else std::cout << ", ";
        }

        std::cout << std::flush;
}

#endif



und


C++:
// bild_test.cc

#include "pixel.hh"
#include "binarypixel.hh"
#include "bild.hh"

int main(void)
{

        bild<binaryPixel> *b1 = new bild<binaryPixel>(2,2);

        pixel *p = b1->getPixel(0);
        p->setValue(1,2,3);

        p = b1->getPixel(1);
        p->setValue(4,5,6);

        p = b1->getPixel(2);
        p->setValue(7,8,9);

        p = b1->getPixel(3);
        p->setValue(10,11,12);

        b1->printImage();

        delete b1;

        return 0;
}



so, wenn ich das kompilieren, bekomme ich keinen Fehler, aber eine 236 KB große Binary, ist das normal??? Naja, das ist nicht das Problem. Das Programm tut genau das, was ich erwarte, aber wenn ich mit valgrind nach memory leaks suche, bekomme ich welche:


Code:
supertux@supertux:~/tmp/kurs/stl>valgrind --tool=addrcheck ./bild_test
==30731== Addrcheck, a fine-grained address checker for x86-linux.
==30731== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==30731== Using valgrind-2.4.0, a program supervision framework for x86-linux.
==30731== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==30731== For more details, rerun with: -v
==30731==
rgb(1, 2, 3), rgb(4, 5, 6)
rgb(7, 8, 9), rgb(10, 11, 12)
==30731==
==30731== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==30731== malloc/free: in use at exit: 1920 bytes in 1 blocks.
==30731== malloc/free: 2 allocs, 1 frees, 1940 bytes allocated.
==30731== For counts of detected errors, rerun with: -v
==30731== searching for pointers to 1 not-freed blocks.
==30731== checked 116608 bytes.
==30731==
==30731== LEAK SUMMARY:
==30731==    definitely lost: 0 bytes in 0 blocks.
==30731==      possibly lost: 0 bytes in 0 blocks.
==30731==    still reachable: 1920 bytes in 1 blocks.
==30731==         suppressed: 0 bytes in 0 blocks.
==30731== Reachable blocks (those to which a pointer was found) are not shown.
==30731== To see them, rerun with: --show-reachable=yes



Warum? Wo habe ich denn einen Fehler gemacht?
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
07.10.2005, 08:37 Uhr
(un)wissender
Niveauwart


Klar verwendest du

Zitat:

an keiner Stelle verwende ich = new datentyp[...];



Siehe

C++:
bild<binaryPixel> *b1 = new bild<binaryPixel>(2,2);



Das mit valgrid kann daran liegen, dass Speicher gecached wird. Ist aber kein Fehler, sondern dient der Optimierung.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
07.10.2005, 13:55 Uhr
Pablo
Supertux
(Operator)



Zitat von (un)wissender:
Klar verwendest du

Zitat:

an keiner Stelle verwende ich = new datentyp[...];



Siehe

C++:
bild<binaryPixel> *b1 = new bild<binaryPixel>(2,2);



Das mit valgrid kann daran liegen, dass Speicher gecached wird. Ist aber kein Fehler, sondern dient der Optimierung.

genau das meinte ich eben nicht, ich meinte, dass ich an keiner Stelle (in den Klassen) sowas habe wie

C++:
int* p = new int[34];



oder so. Ich wollte damit sagen, dass ich offensichtlich nicht vergessen hab ein delete irgendwas, weil ich new nie verwendet habe (ausser bei int main, wo ich delete nicht verwedent habe)
aber wenn ich hab:


C++:
// bild_test.cc

#include "pixel.hh"
#include "binarypixel.hh"
#include "bild.hh"

int main(void)
{

        bild<binaryPixel> b1(2,2); // = new bild<binaryPixel>(2,2);

        pixel *p = b1.getPixel(0);
        p->setValue(1,2,3);

        p = b1.getPixel(1);
        p->setValue(4,5,6);

        p = b1.getPixel(2);
        p->setValue(7,8,9);

        p = b1.getPixel(3);
        p->setValue(10,11,12);

        b1.printImage();

        return 0;
}



dan gibt es es trotzdem 1920 Bytes, die ich selber nie allokiert habe und auch nicht freigegeben werden. Das ist was ich meinte.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.10.2005, 14:07 Uhr
virtual
Sexiest Bit alive
(Operator)


Ist schon, we (un)wissender sagte, steht auch was in valgrinds FAQ zu da.
http://valgrind.org/docs/FAQ/
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
07.10.2005, 14:34 Uhr
Tommix



Hallo,
ein ganz anderer Fehler ist allerdings vermutlich dies:

C++:
binaryPixel::binaryPixel()
{
        ::pixel();
}


Ein expilziter Aufruf des Ctors der Basisklasse sähe so aus:

C++:
binaryPixel::binaryPixel() : pixel()
{
}


ist aber überflüssig, der Aufruf erfolgt in diesem Fall so oder so.
Funktionen, die die Instanz nicht ändern sollten const sein, also z. B.:

C++:
int pixel::get_blue() const
{
        return blue;
}


wobei die explizite Nennung von this hier, wie auch sonst soweit ich sehe, überflüssig ist.

Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
07.10.2005, 15:21 Uhr
Pablo
Supertux
(Operator)


Danke fuer die Hinweise, ich les sie mir spaeter.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
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: