Ваша первая проблема в том, что вы делаете слишком много в нескольких выражениях. Вы должны сломать это.
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 буфер, а затем вы ... назначить этот указатель? Несколько раз? Тогда освободите только результат последнего звонка? Это совершенно не нужно.
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];
}
}
}
Теперь ваша третья проблема. Вы передаете указатель - но только на символ. Вы не проходите в пустоту *. Это означает, что ваша функция не может быть универсальной - 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).
Более того, Си действительно отстой для такой работы. С ++ намного лучше. Например, довольно просто применить функцию к каждому члену массива.