Pointer method of copying arrays? Single operation?

I want the fastest possible way to perform the following type of action:

//given the value of a variable

//copy a different source array in to a destination array

//then I make some changes to some elements in the destination array

//do some stuff with this array

//and later I want to be able to get back to the situation at the start where the Destination array is ready to accept new things copied in to it

I would be ok to copy by "reference" or by "value", but cannot guarantee that the arrays are the same length, I can guarantee the source one will be shorter or equal to the destination's length.

After copying I will want to modify some members in the destination array, I don't mind either way whether these modifications of members do or do not change the values of those members in the source array. I am ok either way with that.

The slow way is:

uint8_t DestArray[40]={0}
uint8_t DestArrayOriginal[40]={0}
uint8_t Source1Array[7]={0,1,2,3,4,5,6};
uint8_t Source2Array[7]={0,1,2,3,4,5,6,7,8};
uint8_t Mode=0;
uint8_t Var2=0;
for(uint8_t k=0; k<sizeof(DestArray); k++){
    DestArrayOriginal[k]=DestArray[k];
  }
//do some stuff which results in the Mode variable getting a value
//and which puts a new value in Var2
if(Mode==1){
  uint8_t Length=sizeof(Source1Array);
  for(uint8_t k=0; k<Length; k++){
    DestArray[k]=Source1Array[k];
  }
}else if(Mode==2){
  LengthToSend=sizeof(Source2Array);
  for(uint8_t k=0; k<Length; k++){
    DestArray[k]=Source2Array[k];
  }
}else if(Mode==3){//and so on, many different modes possible correspoding to many diferent source arrays which can be used
}

//and as I said after the copy I would be doing something like
DestArray[3]=Var2-4;
DestArray[12]=Var2;
//I don't care if Source1Array or Source2Array 's [3] element gets moified here or not
//obviously I don't want Source1Array or Source2Array 's [12] element modified though
//, as they don't have one so such a change would step on other variables in my code

//at some further later points I'd also like to be able to do 
for(uint8_t k=0; k<sizeof(DestArrayOriginal); k++){
    DestArray[k]=DestArrayOriginal[k];
  }

but those for() loops are slow.

But I wondered if there was a pointer based way of doing it. If so it would be effectively just a few operations of the AVR's clock cycle to change a pointer value.

ifMode==1){
  DestArray=Source1Array; //array syntax is aterall just a cover for pointers
}else if(Mode==2){
    DestArray=Source2Array;
}

The thing is this looks like it would lose the reference to whatever DestArray was initialised as, a memory leak which would get worse every time different things were copied to DestArray.

And as Source2Array and Source1Array aren't necessarily the same length, and either of them is shorter than DestArray, real trouble could, I think, crop up if you wrote to the [12] place of DestArray once DestArray had become instead a pointer to Source1Array or Source2Array. And this could cause even more problems if one then makes that return of DestArray's contents to its originals, from a pointer perspective that could wipe over many bytes worth of other variables.

How can I quickly make such copies? How can I, very quickly, fill an array with the contents of a different array, selecting which different array dependng on a variable's value.
Thank you

memcpy()

To copy "by reference", your destination would NOT be an array, it would be a reference (or pointer) to the original array. So it doesn't actually have an inherent length.

Copying by reference will generally be MUCH faster than copying the data. But it won't preserve the original array when you modify via the pointer.

It would look like:

uint8_t * DestArray;
uint8_t * DestArrayOriginal;
uint8_t Source1Array[7]={0,1,2,3,4,5,6};
uint8_t Source2Array[7]={0,1,2,3,4,5,6,7,8};

destArray = Source1Array;  // copy by reference.

destArray[4] = foo;  // yes, array syntax still works with pointer.
                     // both destArray[4] and Source1Array[4] will have new value
                     //  (they are in fact the same memory location.)

I'd be hard pressed to say "copying" by reference is actually copying. Rather, it's referencing. To me, copying implies you're left with two identical, independent instances of the thing.

westfw, thank you
if DestArray were larger than the SourceXArray s in your exmaple, then after the copy by reference DestArray has a maximum length equal to that of the SourceXArray it was made a reference to? So writing to an element in DestArray > Source1Array's length would overflow? If you put foo in to place [15] for example rather than 4? or if you wanted to set DestArray to Source1Array and then later to be set to Source2Array?

As regards memcpy or memmove, its faster than the for loop but not super fast, and its time scales with the length of the array. The syntax should be:
memcpy(DestArray,SourceXArray, sizeof(whichever is larger, in my case DestArray));
?
That syntax would become a problem if DestArray were shorter than SourceXArray and you were using the longer one's length? but is the right way to handle things when you can guarantee that you source array isshorter than your destination?

Correct.

As regards memcpy or memmove, its faster than the for loop but not super fast, and its time scales with the length of the array. The syntax should be:
memcpy(DestArray,SourceXArray, sizeof(whichever is larger, in my case DestArray)); ?

I would say the size should be whichever is shorter. Overflowing the source is bad, but overflowing the destination is catastrophic.

memXXX() can get quite involved, copying multiple bytes at one time on architectures where that is useful, so it tends to get "more better" than a for loop as the size goes up.
I don't know offhand if there is a version of memXXX() that will fill out a larger destination with zeros (or whatever.) C arrays don't have any internal length that the run-time functions can use, so you'd have to specify both lengths.

Padding with zeroes isn't so important, so no need to worry about that. It sems memmove has been my best option, and finding a different point in my program at which to do that copying when I have a bit greater leeway with timings than I'd had when first looking at the situation.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.