template problem

J

J. Wolfram

Hi!



I need to write a template function which accepts a pointer (and a parameter
for the byte-offset between the elements and a parameter for the number of
elements.).

The different possible types which the pointer is pointing at can be for
example:



float[3]

short

byte[4]

....



So for the first type, the size of the first element would be
3*sizeof(float).



I would like to work inside the template function with a whole element, not
with each primitive data type.





The template function I created works perfectly if I use a pointer to an
element which just contains a primitive type.

If the element is array like in this example, the program crashes even
before a single instruction inside the function has been processed:





struct _AElement

{

short Element;

}*APointer;



struct _BElement

{

float Element[3];

}*BPointer;



APointer = (_AElement*)VoidPointer;

LogArray(APointer, 45, 102); // Okay!



BPointer = (_BElement*)VoidPointer;

LogArray(BPointer, 55, 400); // CRASH!





template <class ElementType> DWORD LogArray(ElementType* ArrayPointer, int
ArrayStride, int ArraySize)

{

...

}





What's the problem and what's a working alternative?

I am using the VS .Net 2004.



Thanks for your help!
 
U

ulrich

Hi!



I need to write a template function which accepts a pointer (and a
parameter
for the byte-offset between the elements and a parameter for the number
of
elements.).

The different possible types which the pointer is pointing at can be for
example:



float[3]

short

byte[4]

...



So for the first type, the size of the first element would be
3*sizeof(float).



I would like to work inside the template function with a whole element,
not
with each primitive data type.





The template function I created works perfectly if I use a pointer to an
element which just contains a primitive type.

If the element is array like in this example, the program crashes even
before a single instruction inside the function has been processed:





struct _AElement

{

short Element;

}*APointer;



struct _BElement

{

float Element[3];

}*BPointer;



APointer = (_AElement*)VoidPointer;

LogArray(APointer, 45, 102); // Okay!



BPointer = (_BElement*)VoidPointer;

LogArray(BPointer, 55, 400); // CRASH!





template <class ElementType> DWORD LogArray(ElementType* ArrayPointer,
int
ArrayStride, int ArraySize)

{

...

}

did you verify that the size of ArrayPointer is estimated correctly inside
LogArray()?
i.e. in particular, did you verify that sizeof(*ArrayPointer) ==
3*sizeof(float) in case of ArrayPointer pointing to an object of type
_BElement?
 
K

Kanenas

I need to write a template function which accepts a pointer (and a parameter
for the byte-offset between the elements and a parameter for the number of
elements.).
Sounds dangerous having the caller supply the size of an element. You
could use 'sizeof(ElementType)' within the function instead. It also
looks like you're using C arrays, which aren't as safe as vectors.
Any reason you can't use vector said:
The different possible types which the pointer is pointing at can be for
example:

float[3]
short
byte[4]
...

So for the first type, the size of the first element would be
3*sizeof(float).
Or 'sizeof(float[3])' (though the two expressions should be equal).
[...]
If the element is array like in this example, the program crashes even
before a single instruction inside the function has been processed:

[...]

What's the problem and what's a working alternative?
I tried the skeleton code you gave using g++ (with some print
instructions added to LogArray) and had no errors, which suggests the
crash is due to a bug in VS .Net 2004 or some instruction in LogArray.
Without knowledge of what happens in LogArray, there's no way of
knowing for certain what the problem is or what alternatives will
work. Personally, I'm suspicious of the use of ArrayStride. Here's a
skeleton for LogArray which uses sizeof to get ArrayStride and uses a
vector rather than an array.

template <class ElementType>
DWORD LogArray(std::vector<ElementType> elements)
{
static const size_t ArrayStride = sizeof(ElementType);
size_t ArraySize = elements.size();
std::vector<ElementType>::iterator ArrayPointer=elements.begin();
...
}

If you want ArraySize to indicate how many elements the "array" should
have rather than already has, use elements.capacity() within LogArray
and have users of LogArray call elements.reserve(...).
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,201
Messages
2,571,052
Members
47,656
Latest member
rickwatson

Latest Threads

Top