Il tuo primo problema è che si' fare troppo MODO in poche espressioni. Devi abbatterlo.
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);
}
Ora il tuo secondo problema. Hai malloc un buffer, quindi tu ... assegni a quel puntatore? Ripetutamente? Quindi liberare solo il risultato dell'ultima f call? Questo è assolutamente inutile.
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];
}
}
}
Ora il tuo terzo problema. Passi un puntatore in - ma solo per char. Non si passa nel vuoto *. Ciò significa che la tua funzione non può essere generica - f non può essere applicata a nulla. Abbiamo bisogno di una matrice di void * s, in modo che la funzione possa assumere qualsiasi tipo come argomento. Abbiamo anche bisogno di prendere la dimensione del tipo come argomento in modo da sapere quanto lontano spostarsi lungo 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;
}
}
Abbiamo ancora un altro problema: il ricordo della temperatura. Non lo liberiamo. Né passiamo un argomento di dati utente in f, che gli consentirebbe di restituire memoria allocata su heap che non abbiamo bisogno di liberare. L'unico modo in cui f può funzionare è se restituisce un buffer statico.
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;
}
}
Ora f può operare praticamente su qualsiasi cosa voglia e mantenere lo stato di cui ha bisogno. Ma ancora non liberiamo il buffer. Ora, f restituisce una semplice struttura che ci dice se è necessario liberare il buffer. Questo ci permette anche di liberare o meno il buffer su diverse chiamate di 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);
}
}
Tuttavia, non riesco ancora a capire lo scopo di questa funzione. Tutto questo per sostituire un ciclo for semplice? Il codice che stai cercando di sostituire è più semplice del codice per chiamare la tua funzione, e probabilmente più efficiente e decisamente più potente (possono usare continue/break, per esempio).
Più di questo, C fa davvero schifo per questo tipo di lavoro. Il C++ è di gran lunga migliore. Ad esempio, è piuttosto banale applicare una funzione a ciascun membro di un array.
per quello che serve a questo puntatore per funzionare e quale mappa si desidera implementare, non penso che ne volete alcuni ad esempio il contenitore di mappe di sgi? – Svisstack
È la tipica applicazione "mappa" che puoi trovare praticamente in ogni lingua funzionale. Si invia una lista, una funzione e si restituisce la lista composta come tale: (f (l [1]), ..., f (l [n])). – Lasirc