Ihr erstes Problem zu tun, ist, dass Sie‘ zu viel in einigen Ausdrücken. Sie müssen es aufschlüsseln.
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);
}
Jetzt Ihr zweites Problem. Sie malloc einen Puffer, dann Sie .. diesem Zeiger zuweisen? Wiederholt? Dann frei nur das Ergebnis des letzten f-Anrufs? Das ist völlig unnötig.
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];
}
}
}
Jetzt Ihr drittes Problem. Sie übergeben einen Zeiger in - aber nur zum char. Du gehst nicht in eine Leere *. Dies bedeutet, dass Ihre Funktion nicht generisch sein kann - f kann nicht auf irgendetwas angewendet werden. Wir brauchen ein Array von void * s, damit die Funktion einen beliebigen Typ als Argument annehmen kann. Wir müssen auch die Größe des Typs als Argument nehmen, damit wir wissen, wie weit wir uns entlang des Ziels bewegen müssen.
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;
}
}
Wir haben noch ein anderes Problem - der Speicher von temp. Wir befreien es nicht. Wir übergeben auch kein Benutzerdatenargument in f, das es ermöglichen würde, Heap-allokierten Speicher zurückzugeben, den wir nicht frei haben müssen. Der einzige Weg, auf dem f funktionieren kann, ist, wenn es einen statischen Puffer zurückgibt.
Jetzt kann f auf so ziemlich alles, was es mag, arbeiten und halten, was auch immer es braucht. Aber wir befreien den Puffer immer noch nicht. Nun gibt f eine einfache Struktur zurück, die uns sagt, ob wir den Puffer freigeben müssen. Dies erlaubt uns auch, den Puffer bei verschiedenen Aufrufen von f freizugeben oder nicht freizugeben.
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);
}
}
Allerdings verstehe ich immer noch nicht den Zweck dieser Funktion. All dies um eine einfache for-Schleife zu ersetzen? Der Code, den Sie ersetzen möchten, ist einfacher als der Code zum Aufrufen Ihrer Funktion und wahrscheinlich effizienter und definitiv leistungsfähiger (sie können beispielsweise continue/break verwenden).
Mehr als das, C wirklich saugt für diese Art von Arbeit. C++ ist viel besser. Es ist dort ziemlich trivial, zum Beispiel eine Funktion auf jedes Mitglied eines Arrays anzuwenden.
für das, was Sie brauchen, um diesen Zeiger zu funktionieren und welche Karte, die Sie implementieren möchten, ich glaube nicht, Sie wollen einige zum Beispiel Kartencontainer von sgi? – Svisstack
Es ist die typische 'Karten'-Anwendung, die Sie in praktisch jeder funktionalen Sprache finden können. Sie senden eine Liste, eine Funktion und sie gibt die als solche zusammengesetzte Liste zurück: (f (l [1]), ..., f (l [n])). – Lasirc