Ответ 1
Ваша первая проблема заключается в том, что вы слишком много делаете в нескольких выражениях. Вам нужно сломать его.
void MapArray(void * src, void * dest, void * (f)(void *), size_t n, size_t elem)
{
unsigned int i = 0, j = 0;
void * temp = malloc(elem);
char* csrc = (char*)src;
char* cdest = (char*)dest;
char* ctemp = (char*)temp;
for(i = 0; i<n; i++)
{
csrc++;
cdest++;
ctemp++;
temp = f(csrc);
for(j = 0; j < elem; j++)
{
cdest[i] = ctemp[i];
}
}
free(temp);
}
Теперь ваша вторая проблема. Вы malloc буфер, затем вы.. присваиваете этому указателю? Неоднократно? Тогда освободите только последний результат f-вызова? Это совершенно необязательно.
void MapArray(void * src, void * dest, void * (f)(void *), size_t n, size_t elem)
{
unsigned int i = 0, j = 0;
char* csrc = (char*)src;
char* cdest = (char*)dest;
for(i = 0; i<n; i++)
{
csrc++;
cdest++;
char* ctemp = (char*)f(csrc);
for(j = 0; j < elem; j++)
{
cdest[i] = ctemp[i];
}
}
}
Теперь ваша третья проблема. Вы передаете указатель, но только до char. Вы не проходите в пустоте *. Это означает, что ваша функция не может быть общей - f не может быть применена ни к чему. Нам нужен массив void * s, так что функция может принимать любой тип в качестве аргумента. Нам также нужно взять размер типа в качестве аргумента, чтобы мы знали, как далеко двигаться по dest.
void MapArray(void ** src, void * dest, void * (f)(void *), size_t n, size_t sizeofT)
{
for(unsigned int i = 0; i < n; i++) {
void* temp = f(src[n]);
memcpy(dest, temp, sizeofT);
dest = (char*)dest + sizeofT;
}
}
У нас еще есть другая проблема - память времен. Мы не освобождаем его. Мы также не передаем аргумент данных пользователя в f, что позволит ему возвращать выделенную кучу память, которую нам не нужно освобождать. Единственный способ, с помощью которого f может работать, - это вернуть статический буфер.
void MapArray(void ** src, void * dest, void * (f)(void *, void*), void* userdata, size_t n, size_t sizeofT)
{
for(unsigned int i = 0; i < n; i++) {
void* temp = f(src[n], userdata);
memcpy(dest, temp, sizeofT);
dest = (char*)dest + sizeofT;
}
}
Теперь f может работать практически во всем, что ему нравится, и удерживать любое состояние, в котором оно нуждается. Но мы все равно не освобождаем буфер. Теперь f возвращает простую структуру, которая сообщает нам, нужно ли нам освобождать буфер. Это также позволяет нам освобождать или не освобождать буфер при разных вызовах f.
typedef struct {
void* data;
int free;
} freturn;
void MapArray(void ** src, void * dest, freturn (f)(void *, void*), void* userdata, size_t n, size_t sizeofT)
{
for(unsigned int i = 0; i < n; i++) {
freturn thisreturn = f(src[n], userdata);
void* temp = thisreturn.data;
memcpy(dest, temp, sizeofT);
dest = (char*)dest + sizeofT;
if (thisreturn.free)
free(temp);
}
}
Однако я все еще не понимаю цели этой функции. Все это заменит простой цикл? Код, который вы пытаетесь заменить, проще, чем код для вызова вашей функции и, вероятно, более эффективный и, безусловно, более мощный (например, они могут использовать continue/break).
Более того, C действительно отстой для такого рода работ. С++ намного лучше. Это довольно тривиально, чтобы применить функцию к каждому члену массива, например.