memmove ()? Я предполагаю, что вы намеревались использовать memcpy () или strcpy () или, возможно, даже strncpy ()!
Кроме того, двойные ** (вероятно) не нужны в my_fun(void **data)
Указатель void может указывать на что угодно, включая указатель void. (но это зависит от определения функции, которое не было показано)
В этом случае амперсанд (и отливка) в my_fun ( (void**) &ds);
также не требуется. любой указатель может быть приведен к пустому указателю в C.
my_ds * ds;
ds = malloc(sizeof *ds);
if (len >= sizeof my_ds->static_data) len = sizeof my_ds->static_data - 1;
memcpy(my_ds->static_data, buf, len);
my_ds->static_data[len] = 0;
ds->a = c;
ds->b = d;