switch from raw pointer to vector container

Discussion in 'C++' started by markww, Aug 30, 2006.

  1. markww

    markww Guest

    Hi,

    I want to use the vector container class to store pixel data. Currently
    I have some memory allocated using c++'s new operator. I allocate the
    memory differently based on if the pixel type is unsigned char or
    unsigned short like this:

    int nPixelType = ?; // unsigned short, or unsigned char?
    BYTE *pByte = NULL;
    switch (nPixelType) {
    case UNSIGNED_SHORT:
    pBtye = (BYTE *)new unsigned char[256 * 256];
    break;

    case UNSIGNED_CHAR:
    pByte = (BYTE *)new unsigned char[256 * 256];
    break;
    }

    Then I whenever I was doing image processing tasks, I would create a
    temporary pointer to the data and cast it to the correct type:

    unsigned short *p = (unsigned short *)pByte;
    or
    unsigned char *p = (unsigned char *)pByte;

    Now it was suggested to me that I stop using raw pointers like this in
    favor of vector containers. Can I translate the above into a vector of
    BYTE and accomplish the same thing? Would it be possible to get around
    having to cast the pointer before accessing it everytime?

    vector<BYTE> vNew;
    vNew.resize(256 * 256);

    Thanks
    markww, Aug 30, 2006
    #1
    1. Advertising

  2. markww

    Ron Natalie Guest

    markww wrote:
    > Hi,
    >
    > I want to use the vector container class to store pixel data. Currently
    > I have some memory allocated using c++'s new operator. I allocate the
    > memory differently based on if the pixel type is unsigned char or
    > unsigned short like this:
    >
    > int nPixelType = ?; // unsigned short, or unsigned char?
    > BYTE *pByte = NULL;
    > switch (nPixelType) {
    > case UNSIGNED_SHORT:
    > pBtye = (BYTE *)new unsigned char[256 * 256];
    > break;
    >
    > case UNSIGNED_CHAR:
    > pByte = (BYTE *)new unsigned char[256 * 256];
    > break;
    > }
    >

    This is C++ after all. What's with all the casting and switch
    statements. Either make an abstract base:

    class PixelData {
    public:
    virtual void* GetRawData() = 0;
    virtual void Resize(int width, int height);
    };

    class UnsignedCharPixelData : public PixelData {
    vector<unsigned char> uc_data;
    public:
    virtual void Resize(int width, int height) {
    uc_data.resize(width*height);
    }
    virtual void* GetRawData() { return &uc_data[0]; }
    };

    or use a templated class:

    template <typename PixelType > class PixelData {
    vector<PixelType> pdata;
    public:
    void* GetRawData() { return &pdata[0]; }
    void Resize(int w, int h) {
    pdata.resize(w*h);
    }
    };
    Ron Natalie, Aug 31, 2006
    #2
    1. Advertising

  3. markww

    Jim Langston Guest

    "markww" <> wrote in message
    news:...
    > Hi,
    >
    > I want to use the vector container class to store pixel data. Currently
    > I have some memory allocated using c++'s new operator. I allocate the
    > memory differently based on if the pixel type is unsigned char or
    > unsigned short like this:
    >
    > int nPixelType = ?; // unsigned short, or unsigned char?
    > BYTE *pByte = NULL;
    > switch (nPixelType) {
    > case UNSIGNED_SHORT:
    > pBtye = (BYTE *)new unsigned char[256 * 256];
    > break;
    >
    > case UNSIGNED_CHAR:
    > pByte = (BYTE *)new unsigned char[256 * 256];
    > break;
    > }
    >
    > Then I whenever I was doing image processing tasks, I would create a
    > temporary pointer to the data and cast it to the correct type:
    >
    > unsigned short *p = (unsigned short *)pByte;
    > or
    > unsigned char *p = (unsigned char *)pByte;
    >
    > Now it was suggested to me that I stop using raw pointers like this in
    > favor of vector containers. Can I translate the above into a vector of
    > BYTE and accomplish the same thing? Would it be possible to get around
    > having to cast the pointer before accessing it everytime?
    >
    > vector<BYTE> vNew;
    > vNew.resize(256 * 256);
    >
    > Thanks


    There are a few ways to accomplish this, including a class that keeps track
    of the type of data it is and allocates appropriately, or templates, or
    polymorphism (Pixel as base class, PixelShort or PixelChar as derived
    classes), etc...

    A vector container, itself, isn't a solution other than storing the data.
    You still have to decide what type of data to store.
    Jim Langston, Aug 31, 2006
    #3
  4. markww

    markww Guest

    Jim Langston wrote:
    > "markww" <> wrote in message
    > news:...
    > > Hi,
    > >
    > > I want to use the vector container class to store pixel data. Currently
    > > I have some memory allocated using c++'s new operator. I allocate the
    > > memory differently based on if the pixel type is unsigned char or
    > > unsigned short like this:
    > >
    > > int nPixelType = ?; // unsigned short, or unsigned char?
    > > BYTE *pByte = NULL;
    > > switch (nPixelType) {
    > > case UNSIGNED_SHORT:
    > > pBtye = (BYTE *)new unsigned char[256 * 256];
    > > break;
    > >
    > > case UNSIGNED_CHAR:
    > > pByte = (BYTE *)new unsigned char[256 * 256];
    > > break;
    > > }
    > >
    > > Then I whenever I was doing image processing tasks, I would create a
    > > temporary pointer to the data and cast it to the correct type:
    > >
    > > unsigned short *p = (unsigned short *)pByte;
    > > or
    > > unsigned char *p = (unsigned char *)pByte;
    > >
    > > Now it was suggested to me that I stop using raw pointers like this in
    > > favor of vector containers. Can I translate the above into a vector of
    > > BYTE and accomplish the same thing? Would it be possible to get around
    > > having to cast the pointer before accessing it everytime?
    > >
    > > vector<BYTE> vNew;
    > > vNew.resize(256 * 256);
    > >
    > > Thanks

    >
    > There are a few ways to accomplish this, including a class that keeps track
    > of the type of data it is and allocates appropriately, or templates, or
    > polymorphism (Pixel as base class, PixelShort or PixelChar as derived
    > classes), etc...
    >
    > A vector container, itself, isn't a solution other than storing the data.
    > You still have to decide what type of data to store.


    Hi guys,

    If I write a class to do it like posted, how could I keep a list of
    them - eventually I want to keep the following:

    vector<CPixelContainerClass> vImageStack;

    the first image in the stack might have to be allocated as unsigned
    char, the second might have to be allocated as unsigned short.
    markww, Aug 31, 2006
    #4
  5. markww

    David Harmon Guest

    On 30 Aug 2006 16:44:23 -0700 in comp.lang.c++, "markww"
    <> wrote,
    >If I write a class to do it like posted, how could I keep a list of
    >them - eventually I want to keep the following:
    >
    > vector<CPixelContainerClass> vImageStack;


    First let me say that I agree with several other posters -- if you
    have those casts scattered all over your code, and deal with both
    shorts and chars all over your code, your life will be miserable.
    You really need to encapsulate all that into a family of classes.

    Your base class would probably have something like virtual
    get_pixel() and put_pixel() functions, and derived classes would
    convert a common pixel representation to and from whatever more
    compact form they were using internally in the implementation of
    those functions.

    So your vector will probably know only about an abstract base class.
    And that means it has to store some kind of pointer, so that it can
    point to instances of your derived classes.

    The vector can store raw pointers, but that means _all_ the memory
    management is up to you. Or the vector can store some kind of smart
    pointer class such as boost::scoped_ptr (http://boost.org) so that
    it can clean up for itself automatically.
    David Harmon, Aug 31, 2006
    #5
  6. markww

    Pete Becker Guest

    David Harmon wrote:
    >
    > The vector can store raw pointers, but that means _all_ the memory
    > management is up to you. Or the vector can store some kind of smart
    > pointer class such as boost::scoped_ptr (http://boost.org) so that
    > it can clean up for itself automatically.
    >


    Or std::tr1::shared_ptr.
    Pete Becker, Aug 31, 2006
    #6
  7. markww

    David Harmon Guest

    On Wed, 30 Aug 2006 21:09:08 -0400 in comp.lang.c++, Pete Becker
    <> wrote,
    >David Harmon wrote:
    >>
    >> The vector can store raw pointers, but that means _all_ the memory
    >> management is up to you. Or the vector can store some kind of smart
    >> pointer class such as boost::scoped_ptr (http://boost.org) so that
    >> it can clean up for itself automatically.
    >>

    >
    >Or std::tr1::shared_ptr.


    But in this case it does not appear that sharing is needed.
    Is there a tr1 scoped_ptr? Is tr1 a sports car from Triumph?
    I know I can get a boost for free, but probably not a sports car.
    David Harmon, Aug 31, 2006
    #7
  8. markww

    Jim Langston Guest

    "markww" <> wrote in message
    news:...
    >
    > Jim Langston wrote:
    >> "markww" <> wrote in message
    >> news:...
    >> > Hi,
    >> >
    >> > I want to use the vector container class to store pixel data. Currently
    >> > I have some memory allocated using c++'s new operator. I allocate the
    >> > memory differently based on if the pixel type is unsigned char or
    >> > unsigned short like this:
    >> >
    >> > int nPixelType = ?; // unsigned short, or unsigned char?
    >> > BYTE *pByte = NULL;
    >> > switch (nPixelType) {
    >> > case UNSIGNED_SHORT:
    >> > pBtye = (BYTE *)new unsigned char[256 * 256];
    >> > break;
    >> >
    >> > case UNSIGNED_CHAR:
    >> > pByte = (BYTE *)new unsigned char[256 * 256];
    >> > break;
    >> > }
    >> >
    >> > Then I whenever I was doing image processing tasks, I would create a
    >> > temporary pointer to the data and cast it to the correct type:
    >> >
    >> > unsigned short *p = (unsigned short *)pByte;
    >> > or
    >> > unsigned char *p = (unsigned char *)pByte;
    >> >
    >> > Now it was suggested to me that I stop using raw pointers like this in
    >> > favor of vector containers. Can I translate the above into a vector of
    >> > BYTE and accomplish the same thing? Would it be possible to get around
    >> > having to cast the pointer before accessing it everytime?
    >> >
    >> > vector<BYTE> vNew;
    >> > vNew.resize(256 * 256);
    >> >
    >> > Thanks

    >>
    >> There are a few ways to accomplish this, including a class that keeps
    >> track
    >> of the type of data it is and allocates appropriately, or templates, or
    >> polymorphism (Pixel as base class, PixelShort or PixelChar as derived
    >> classes), etc...
    >>
    >> A vector container, itself, isn't a solution other than storing the data.
    >> You still have to decide what type of data to store.

    >
    > Hi guys,
    >
    > If I write a class to do it like posted, how could I keep a list of
    > them - eventually I want to keep the following:
    >
    > vector<CPixelContainerClass> vImageStack;
    >
    > the first image in the stack might have to be allocated as unsigned
    > char, the second might have to be allocated as unsigned short.


    Well, if you want to store them that way, instead of pointers, then you
    don't want to use polymorphism. So basically, just have your
    CPixelContainerClass keep track of how it's stored.

    enum PixelTypes
    {
    ShortPixels,
    CharPixels
    };

    class CPixelContainerClass
    {
    public:
    CPixelContainerClass( const PixelTypes pt ): PixelType_( pt ),
    ShortPixel_( NULL ), CharPixel_( NULL ) {}
    ~CPixelContainerClass() { delete[] ShortPixel_; delete[] CharPixel_; }
    PixelTypes Type() const { return PixelType_; }
    void LoadData( char* Data, const int Size )
    {
    if ( PixelType_ == ShortPixels )
    // Allocate and load data into ShortPixel_
    else
    // Allocate and load data into CharPixel_
    }
    private:
    PixelTypes PixelType_;
    unsigned short* ShortPixel_;
    unsigned char* CharPixel_;
    }

    There are other ways to design this class, and maybe better ways, but you
    should get the idea. You are encapsulating the data, so any class that uses
    CPixelContainerClass shouldn't have to care if the data is stored in
    unsigned short or unsigned char, let the class handle that trivia. If, at
    some point, you do need to know outside the class, use .Type() to see how
    it's stored.

    This is not polymorphism, and I really don't think polymorphism is the way
    to go. Personally, I might just use one pointer (unsigned char* as it's
    only 1 byte) for all the data and just treat it different if PixelType_ ==
    ShortPixels.

    The advantage of this is you just have your vector of CPixelContainerClass
    and it doesn't matter what type the data is inside of it, they are just
    isntances of the same class.

    I can think of off the top of my head 3 or 4 other ways to do the same
    thing, such as having the pixel data itself stored in another class of
    different types, etc...

    It's hard to say without knowing your design constraints the best way to do
    it.
    Jim Langston, Aug 31, 2006
    #8
  9. markww

    Pete Becker Guest

    David Harmon wrote:

    > Is tr1 a sports car from Triumph?


    TR1 is the first Technical Report on C++ Library Extensions.
    Pete Becker, Aug 31, 2006
    #9
  10. markww

    David Harmon Guest

    On Thu, 31 Aug 2006 06:51:43 -0400 in comp.lang.c++, Pete Becker
    <> wrote,
    >
    >TR1 is the first Technical Report on C++ Library Extensions.


    So I have to buy _The C++ Standard Library Extensions: a Tutorial
    and Reference_ in order to find out if it has scoped_ptr?
    David Harmon, Aug 31, 2006
    #10
  11. markww

    Jens Theisen Guest

    David Harmon wrote:
    > But in this case it does not appear that sharing is needed.


    It's needed if you want to put it in a vector (CopyConstructible and
    CopyAssignable requirements).

    Jens
    Jens Theisen, Aug 31, 2006
    #11
  12. markww

    Pete Becker Guest

    David Harmon wrote:

    > On Thu, 31 Aug 2006 06:51:43 -0400 in comp.lang.c++, Pete Becker
    > <> wrote,
    >
    >>TR1 is the first Technical Report on C++ Library Extensions.

    >
    >
    > So I have to buy _The C++ Standard Library Extensions: a Tutorial
    > and Reference_ in order to find out if it has scoped_ptr?
    >


    No, you can get the text of TR1 at
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf. But
    you should buy my book anyway. <g>

    TR1 doesn't have scoped_pointer.
    Pete Becker, Aug 31, 2006
    #12
  13. markww

    Noah Roberts Guest

    David Harmon wrote:
    > On Wed, 30 Aug 2006 21:09:08 -0400 in comp.lang.c++, Pete Becker
    > <> wrote,
    > >David Harmon wrote:
    > >>
    > >> The vector can store raw pointers, but that means _all_ the memory
    > >> management is up to you. Or the vector can store some kind of smart
    > >> pointer class such as boost::scoped_ptr (http://boost.org) so that
    > >> it can clean up for itself automatically.
    > >>

    > >
    > >Or std::tr1::shared_ptr.

    >
    > But in this case it does not appear that sharing is needed.
    > Is there a tr1 scoped_ptr?


    No.

    > Is tr1 a sports car from Triumph?


    No, but Pete Becker works for Dinkumware, the only company you can get
    the complete TR1 from. He also wrote what seems to be the only book on
    the subject besides the TR1 document itself. However, you don't need
    to buy either to get std::tr1::shared_ptr.

    > I know I can get a boost for free, but probably not a sports car.


    std::tr1::shared_ptr is the same class as boost::shared_ptr. Much of
    TR1 is from boost and can be downloaded with boost. Boost includes a
    tr1 header implementation that includes the right classes and places
    them in std::tr1. Things you don't get are the math functions and
    according to the boost help the unordered associative containers.
    Noah Roberts, Aug 31, 2006
    #13
  14. markww

    David Harmon Guest

    On Thu, 31 Aug 2006 15:49:31 +0100 in comp.lang.c++, Jens Theisen
    <> wrote,
    >David Harmon wrote:
    >> But in this case it does not appear that sharing is needed.

    >
    >It's needed if you want to put it in a vector (CopyConstructible and
    >CopyAssignable requirements).


    Thanks for the correction. I was thinking the vector owns the whole
    thing, so no need, but clearly that's not good enough when the
    vector has to copy the pointer.
    David Harmon, Sep 1, 2006
    #14
  15. markww

    David Harmon Guest

    On Thu, 31 Aug 2006 11:49:06 -0400 in comp.lang.c++, Pete Becker
    <> wrote,
    >TR1 doesn't have scoped_pointer.


    As Jens points out, it wouldn't do anyway.
    David Harmon, Sep 1, 2006
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vivi Orunitia
    Replies:
    11
    Views:
    4,470
    Martijn Lievaart
    Feb 4, 2004
  2. Replies:
    8
    Views:
    1,914
    Csaba
    Feb 18, 2006
  3. ehui928
    Replies:
    2
    Views:
    461
    ehui928
    May 29, 2006
  4. Replies:
    2
    Views:
    399
    Juha Nieminen
    Sep 8, 2008
  5. Hicham Mouline
    Replies:
    100
    Views:
    2,079
    Noah Roberts
    Aug 25, 2009
Loading...

Share This Page