-1

I'm trying to iteratively copy an unsigned char array to a uint_32t variable (in 4 byte blocks), perform some operation on the uint_32t variable, and copy it back to the unsigned char array.

Here's my code:

unsigned char byteArray[len]
for (int i=0; i<len; i+=4) {
  uint32_t tmpInt = 0;
  memcpy(&tmpInt, byteArray+(i*4), sizeof(uint32_t));
  // do some operation on tmpInt here
  memcpy((void*)(byteArray+(i*4)), &tmpInt, sizeof(uint32_t));
}

It doesn't work though. What's wrong, and how can I achieve what I want to do?

alk
  • 69,737
  • 10
  • 105
  • 255
user1118764
  • 9,255
  • 18
  • 61
  • 113

2 Answers2

4

The problem is that you are adding 4 to i with each iteration and multiplying by 4. You should be using byteArray + i.

Also, as @WeatherVane pointed out below, your loop would be more consistent with a sizeof():

for (int i = 0; i < len; i += sizeof(uint32_t)).

D.Go
  • 171
  • 9
2

As others pointed out you are doing too much by incrementing i as well as multiplying it by the size of your target.

On top of this

  • the code shown might run into a buffer overflow issue reading beyond the source array.
  • the sizeof operator evaluates to size_t not int.
  • the code repeats defining the size of the target independently several times.

Fixing all, the result might look like this:

  unsigned char byte_array[len];

  typedef uint32_t target_type;
  const size_t s = sizeof (target_type);

  for (size_t i = 0; i < (len/s)*s; i += s) {
    target_type target;
    memcpy(&target, byte_array + i, s);

    // do some operation on target here

    memcpy(byte_array + i, &target, s);
  }

To avoid the typedef just define the target outside of the for-loop:

  unsigned char byte_array[len];

  {
    uint32_t target;
    const size_t s = sizeof target;

    for (size_t i = 0; i < (len/s)*s; i += s) {
      memcpy(&target, byte_array + i, s);

      // do some operation on target here

      memcpy(byte_array + i, &target, s);
    }
  }

An equivalent to

byte_array + i

would be

&byte_array[i]

which might be more intuitively to read.

To avoid the "strange" (len/s)*s one could step away from using an index at all, but use a pointer instead:

for (unsigned char p = byte_array; p < byte_array + len; p += s) {
      memcpy(&target, p, s);

      // do some operation on target here

      memcpy(p, &target, s);
    }

In my opinion this is a more elegant solution.

dda
  • 6,030
  • 2
  • 25
  • 34
alk
  • 69,737
  • 10
  • 105
  • 255