Sign in to follow this  

Function modify another function's local variable

Recommended Posts

Ok, I am currently writing a CustomUInt64 class, this class is just a way to represent an unsigned int of 64 bit. My problem is that while testing some of its functionality I wrote a little test, one part of this test involved some arrays and to make everything easier I wrote some functions to modify these arrays. In my main function I have some arrays of different types, the declaration looks like this:
CustomUInt64 U64Array[200];
UInt8	U8Array[25];
UInt16	U16Array[25];
UInt32	U32Array[25];
SInt8	S8Array[25];
SInt16	S16Array[25];
SInt32	S32Array[25];
Float32	F32Array[25];
Float64	F64Array[25];

These types are just "typedef"s UInt8/UInt16/UInt32 = unsigned char/unsigned short/unsigned int SInt8/SInt16/SInt32 = signed char/signed short/signed int Float32/Float64 = float/double As I said these are declared inside main, so no function should be able to access them without having a reference or pointer passed right? (I have no global variables) My problem is that a function which get passed U64Array and U16Array modify U8Array, when I later call the same function with the other arrays U8Array is also modified. The other arrays is also modified, but in different calls. The function which changes U8Array is this:
template<typename T,typename T2,size_t Size>
void CopyArray(T *p_DestArray,const T2 (&p_SrcArray)[Size],UInt32 p_DestStart = 0,UInt32 p_SrcStart = 0)
	for(int i = 0;i<Size;++i)
		p_DestArray[i+p_DestStart] = static_cast<T>(p_SrcArray[i+p_SrcStart]);

The function is called in this code block, I have added some comment to describe when the arrays become invalid, when I say this I mean the function call on the same line, so "this changes x" means that x is a different value on the next line.:
CopyArray<UInt8,CustomUInt64>	(U8Array,	U64Array,	0,	0);		// This changes all values of U64Array
CopyArray<UInt16,CustomUInt64>	(U16Array,	U64Array,	0,	25);	// This changes all values of U64Array and U8Array
CopyArray<UInt32,CustomUInt64>	(U32Array,	U64Array,	0,	50);	// This changes all values of U16Array, U64Array and U8Array
CopyArray<SInt8,CustomUInt64>	(S8Array,	U64Array,	0,	75);	// This changes all values of U32Array, U16Array, U64Array and U8Array
CopyArray<SInt16,CustomUInt64>	(S16Array,	U64Array,	0,	100);
CopyArray<SInt32,CustomUInt64>	(S32Array,	U64Array,	0,	125);
CopyArray<Float32,CustomUInt64>	(F32Array,	U64Array,	0,	150);
CopyArray<Float64,CustomUInt64>	(F64Array,	U64Array,	0,	175);

Before these calls to CopyArray I also called them, but nothing went wrong there, those function calls looked like this:

So does anyone have an idea of what could have went wrong?

Share this post

Link to post
Share on other sites
It sounds like when you are writing to one array (probably U64Array or U16Array), you are writing past the end and overwriting parts of U8Array.

Share this post

Link to post
Share on other sites
Original post by JohnBolton
It sounds like when you are writing to one array (probably U64Array or U16Array), you are writing past the end and overwriting parts of U8Array.

I had already checked that, but I went looking again and realized that the number of components I was copying was the number of elements in the source array because when I first wrote it I intented to use it for copying smaller arrays into a bigger one, but here I copied from a 200 element array(of 8 bytes each) to arrays as small as 50 elements of 1 byte.

Thanks for the help, I'll try to fix the code now.

Share this post

Link to post
Share on other sites
Original post by CTar
The function which changes U8Array is this:
*** Source Snippet Removed ***

This attempts to copy n elements out of the source array, starting at k and ranging to k+n-1 inclusive, where n is the number of elements the source array has, and k is not necessarily 0. And that's bad. Similarly, the destination array may overflow. In your case you're "lucky" enough that the data is overflowing into (an)other array(s).

In any case, why are you writing this? Look up std::copy; it provides the necessary functionality for pointers, and you can wrap it (instead of writing a for loop) for arrays to make use of their sizes:

template<typename T, typename T2, size_t srcSize, size_t destSize>
void CopyAsMuchAsPossible(
const T (&dest)[destSize], const T2 (&src)[srcSize],
size_t destBegin = 0, size_t srcBegin = 0) {
size_t elementCount = std::min(srcSize - srcBegin, destSize - destBegin);
std::copy(src + srcBegin, src + srcBegin + elementCount, dest + destBegin);

template<typename OutputIterator, typename T, size_t srcSize>
// Another version, blindly assuming that the destination can hold the data,
// and taking an iterator for that destination (e.g. a pointer) rather than
// an array.
void CopyBlindlyToEndOfArray(
OutputIterator& dest, const T (&src)[srcSize], size_t srcBegin = 0) {
std::copy(src + srcBegin, src + srcSize, dest);

// spiffy example
Thing[NUM_THINGS] things;
std::vector<Thing> allButOne;
CopyBlindlyToEndOfArray(std::back_inserter(allButOne), things, 1);
// Although all the wrapper really does is check the endpoint for you:
std::copy(things + 1, things + NUM_THINGS, std::back_inserter(allButOne));
// equivalent (unless I messed up somewhere)

Share this post

Link to post
Share on other sites
By making your code human-readable:

CopyArray(A,B,a,b) means:

copy the values of B between B[b] and B[b + size(B)]
put them between A[a] and A[a + size(B)]

Red code should ring a bell: it's invalid for b != 0.
Also, yellow code is very risky: it's invalid if B is larger than A or if a is too big.

In the calls you made, you made both mistakes.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this