Click here to Skip to main content
16,015,351 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to figure out how to shift an array.

Say I have an array int data=[20];

and wanted to shift right so data [19] is gone and 18 moves to 19. Then I would fill [0] with a new number.

Would I have to use Something like

C#
for (i=19, i<=0, i--)
{
    data[i]=data[i-1]
}



or would I use something like memmove?

Thanks for the help
Posted
Updated 12-May-11 5:20am
v2

[In support of @OriginalGriff Answer:]

using memmove you will gain performance but at an expense of readability and a chance to shoot yourself in the foot. Remember you are dealing with raw mem locations and slight shift can have.... you know what I mean.

If you are dealing with small set of data, then stick with for loop. It is readable, not hard to write and easy to debug and maintain, but it will have performance hit as compared to memmove.

If you are dealing with very large set of data, then memmove may be your friend, but handle with care. Remember you still need to over-write your first index (index 0 in this case) once you move your data.

BTW: as I pointed out, @originalgriff's code needs some improvements, like this

const int SIZE = 20;
memmove(data+1, data, (sizeof(int)*(SIZE-1)));
 
Share this answer
 
Comments
Member 7796364 12-May-11 13:08pm    
I am only dealing with a data set of 20, So looks like the for loop would be best.

Thanks for the help
OriginalGriff 12-May-11 14:41pm    
You are right about the third parameter, but I'm not sure about the performance - it will vary depending on the size of the memory block. Remember that you need an allocate, copy and then copy back, so there will probably be a break even point when the for loop is more efficient!
Gets my five for the correction though!
Just thought I would give you a number of solutions that you can play with.
Interesting - no one noted that even as pseudo code that 'for' loop example is invalid.
#include <algorithm> // if C++ copy_backward() function template is used
#include <cstring>   // if C memmove function is used

typedef int T; // defined to generalize the solutions

// Solution 1: If pointer to memory holding 20 elements of type T
//   Exmple: T* data = new T[array_size];
const size_t array_size = 20;
std::copy_backward (data, data+array_size-1, data+array_size);
data[0] = 0;

// Solution 2: If an array of elements of type T
//   Exmple: T data[20];
const size_t array_size = sizeof(data)/sizeof(data[0]);
std::copy_backward (data, data+array_size-1, data+array_size);
data[0] = 0;

// Solution 3: Alternate solution to solutions 1 & 2
for( size_t i = array_size-1; i > 0; --i )
{
	data[i] = data[i-1]; // OR *(data+i) = *(data + (i-1));
}
data[0] = 0;

// Solution 4: Alternate solution to 3 - should be faster than 3
size_t i = array_size;
while( --i > 0 )
{
	data[i] = data[i-1]; // OR *(data+i) = *(data + (i-1));
}
data[0] = 0;

// Solution 5: Same as calling copy_backward() in solution 1 & 2
T* first = data + 1;
T* last = data + array_size - 1;
T* dest = data + array_size;
while( last != first )
{
	*(--dest) = *(--last);
}
data[0] = 0;

// Solution 6: If type T is a POD - built-in type or C-style structure
// Notes:
//   1. memmove() is normally implemented in assembly - should be fastest method
//   2. STL implementors often create specialized (optimized) versions of their
//      algorithms that call memmove() for built-in types like char, int, etc.
memmove(data+1, data, sizeof(data)-sizeof(data[0]));
data[0] = 0;
 
Share this answer
 
v4
Comments
Member 7796364 18-May-11 7:37am    
Thanks I will take a look at these. I had just typed the code here. When i implemented it I added the correct syntax
C#
int newNum;
for (int i=19;i>0;i--)
    {
        a[i]=a[i-1];
    }
    a[0]=nuwNum;
 
Share this answer
 
v2
You can't easily do it with memmove, because you want to shift it all right one place:
memmove (data + 1,data,19);
will copy the first byte through the whole of "data"!
I would stick with the for loop - it's pretty obvious and it saves creating an intermediate copy of the data, which you would need for memmove
 
Share this answer
 
Comments
Yusuf 12-May-11 12:10pm    
@OriginalGriff,
I agree it would be readable to use for loop rather than memmove.

Memmove the third parameter is in bytes, so it should have been

memmove(data+1, data, (sizeof(int)*(SIZE-1)));

Where SIZE = 20
krmed 12-May-11 13:42pm    
memmove will not replicate the first byte throughout all of "data".

According to MSDN:
If some regions of the source area and the destination overlap, both functions ensure that the original source bytes in the overlapping region are copied before being overwritten.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900