Skip to content

Instantly share code, notes, and snippets.

@stevenjohnstone
Created November 20, 2025 10:46
Show Gist options
  • Select an option

  • Save stevenjohnstone/6db4013576ceab49e8957ce1cc3ef6ca to your computer and use it in GitHub Desktop.

Select an option

Save stevenjohnstone/6db4013576ceab49e8957ce1cc3ef6ca to your computer and use it in GitHub Desktop.
Memcpy optimisation fun with overlapping pointers

This demos how memcpy can go badly wrong when used to remove an element of an array by shifting content left.

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct foo {
  int a;
  int b;
};

int main(int argc, const char **argv) {
  char data[16];
  for (int i = 0; i < sizeof(data); i++) {
          data[i] = (char)i;
  }

  struct foo *dst = malloc(sizeof(struct foo) * sizeof(data));

  for (int i = 0; i < sizeof(data); i++) {
    dst[i].a = i;
    dst[i].b = i;
  }

  // removes zeroeth element
  memcpy(&dst[0], &dst[1], sizeof(struct foo) * (sizeof(data) - 1));

  bool bad = false;
  for (int i = 0; i < (sizeof(data) - 1); i++) {
    fprintf(stderr, "(%d %d)", dst[i].a, dst[i].b);
    if (dst[i].a != i + 1) {
            fprintf(stderr, " expected (%d %d)", i+1, i+1);
            bad = true;
    }
    fprintf(stderr, "\n");
  }
  printf("\n");
  assert (!bad);
  return 0;
}

Compile with clang without optimisation and run

clang memcpy.c -o memcpy
./memcpy
(1 1)
(2 2)
(3 3)
(4 4)
(5 5)
(6 6)
(7 7)
(8 8)
(9 9)
(10 10)
(11 11)
(12 12)
(13 13)
(14 14)
(15 15)

So far so good...

Now try with -O2

clang memcpy.c -O2 -o memcpy
./memcpy
(1 1)
(2 2)
(3 3)
(4 4)
(5 5)
(6 6)
(7 7)
(9 9) expected (8 8)
(9 9)
(10 10)
(11 11)
(12 12)
(13 13)
(14 14)
(15 15)

Assertion failed: (!bad), function main, file memcpy.c, line 38.
[1]    84171 abort      ./memcpy

Tested on

# clang -v
Apple clang version 17.0.0 (clang-1700.4.4.1)
Target: arm64-apple-darwin25.1.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
# sysctl -n machdep.cpu.brand_string
Apple M3 Ultra
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment