468,512 Members | 1,346 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,512 developers. It's quick & easy.

switch from raw pointer to vector container

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<BYTEvNew;
vNew.resize(256 * 256);

Thanks

Aug 30 '06 #1
14 3313
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 charuc_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<PixelTypepdata;
public:
void* GetRawData() { return &pdata[0]; }
void Resize(int w, int h) {
pdata.resize(w*h);
}
};
Aug 30 '06 #2
"markww" <ma****@gmail.comwrote in message
news:11**********************@e3g2000cwe.googlegro ups.com...
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<BYTEvNew;
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.
Aug 30 '06 #3

Jim Langston wrote:
"markww" <ma****@gmail.comwrote in message
news:11**********************@e3g2000cwe.googlegro ups.com...
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<BYTEvNew;
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<CPixelContainerClassvImageStack;

the first image in the stack might have to be allocated as unsigned
char, the second might have to be allocated as unsigned short.

Aug 30 '06 #4
On 30 Aug 2006 16:44:23 -0700 in comp.lang.c++, "markww"
<ma****@gmail.comwrote,
>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<CPixelContainerClassvImageStack;
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.
Aug 31 '06 #5
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.
Aug 31 '06 #6
On Wed, 30 Aug 2006 21:09:08 -0400 in comp.lang.c++, Pete Becker
<pe********@acm.orgwrote,
>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.

Aug 31 '06 #7
"markww" <ma****@gmail.comwrote in message
news:11**********************@m79g2000cwm.googlegr oups.com...
>
Jim Langston wrote:
>"markww" <ma****@gmail.comwrote in message
news:11**********************@e3g2000cwe.googlegr oups.com...
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<BYTEvNew;
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<CPixelContainerClassvImageStack;

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.
Aug 31 '06 #8
David Harmon wrote:
Is tr1 a sports car from Triumph?
TR1 is the first Technical Report on C++ Library Extensions.
Aug 31 '06 #9
On Thu, 31 Aug 2006 06:51:43 -0400 in comp.lang.c++, Pete Becker
<pe********@acm.orgwrote,
>
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?

Aug 31 '06 #10
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
Aug 31 '06 #11
David Harmon wrote:
On Thu, 31 Aug 2006 06:51:43 -0400 in comp.lang.c++, Pete Becker
<pe********@acm.orgwrote,
>>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/wg...2005/n1836.pdf. But
you should buy my book anyway. <g>

TR1 doesn't have scoped_pointer.
Aug 31 '06 #12

David Harmon wrote:
On Wed, 30 Aug 2006 21:09:08 -0400 in comp.lang.c++, Pete Becker
<pe********@acm.orgwrote,
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.

Aug 31 '06 #13
On Thu, 31 Aug 2006 15:49:31 +0100 in comp.lang.c++, Jens Theisen
<jt***@arcor.dewrote,
>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.

Sep 1 '06 #14
On Thu, 31 Aug 2006 11:49:06 -0400 in comp.lang.c++, Pete Becker
<pe********@acm.orgwrote,
>TR1 doesn't have scoped_pointer.
As Jens points out, it wouldn't do anyway.

Sep 1 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Tommy Lang | last post: by
11 posts views Thread by Vivi Orunitia | last post: by
7 posts views Thread by john townsley | last post: by
34 posts views Thread by Adam Hartshorne | last post: by
18 posts views Thread by silversurfer | last post: by
19 posts views Thread by Michael | last post: by
18 posts views Thread by Goran | last post: by
13 posts views Thread by Phil Bouchard | last post: by
reply views Thread by NPC403 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.