vấn đề đầu tiên của bạn là bạn' đang làm WAY quá nhiều trong một vài biểu thức. Bạn cần phải phá vỡ nó xuống.
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);
}
Bây giờ, vấn đề thứ hai của bạn. Bạn malloc một bộ đệm, sau đó bạn .. gán cho con trỏ đó? Nhiều lần? Sau đó, chỉ miễn phí kết quả của cuộc gọi f cuối cùng? Điều này là hoàn toàn không cần thiết.
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];
}
}
}
Bây giờ, vấn đề thứ ba của bạn. Bạn vượt qua một con trỏ trong - nhưng chỉ để char. Bạn không vượt qua trong một khoảng trống *. Điều này có nghĩa rằng chức năng của bạn không thể được chung chung - f không thể được áp dụng cho bất cứ điều gì. Chúng ta cần một mảng void * s, để hàm có thể lấy bất kỳ kiểu nào làm đối số. Chúng ta cũng cần phải lấy kích thước của kiểu như một đối số để chúng ta biết cách di chuyển dọc theo 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;
}
}
Chúng tôi vẫn còn một vấn đề khác - bộ nhớ tạm thời. Chúng tôi không giải phóng nó. Chúng tôi cũng không chuyển đối số dữ liệu người dùng vào f, điều này cho phép nó trả về bộ nhớ được cấp phát heap mà chúng tôi không cần phải giải phóng. Cách duy nhất trong đó f có thể làm việc là nếu nó trả về một bộ đệm tĩnh.
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;
}
}
Bây giờ f có thể hoạt động trên mọi thứ bạn thích và giữ bất kỳ trạng thái nào cần. Nhưng chúng tôi vẫn không giải phóng bộ đệm. Bây giờ, f trả về một cấu trúc đơn giản cho chúng ta biết nếu chúng ta cần giải phóng bộ đệm. Điều này cũng cho phép chúng tôi giải phóng hoặc không giải phóng bộ đệm trên các cuộc gọi khác nhau của 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);
}
}
Tuy nhiên, tôi vẫn không hiểu mục đích của chức năng này. Tất cả điều này để thay thế một vòng lặp đơn giản? Mã mà bạn đang cố gắng thay thế đơn giản hơn mã để gọi hàm của bạn và có thể hiệu quả hơn, và chắc chắn mạnh hơn (ví dụ: họ có thể sử dụng tiếp tục/ngắt).
Hơn thế nữa, C thực sự hút cho loại công việc này. C++ tốt hơn nhiều. Nó khá tầm thường ở đó để áp dụng một hàm cho mỗi thành viên của một mảng, ví dụ.
cho những gì bạn cần con trỏ này hoạt động và bản đồ bạn muốn triển khai, tôi không nghĩ bạn muốn một số bản đồ ví dụ chứa từ sgi? – Svisstack
Đó là ứng dụng 'bản đồ' điển hình mà bạn có thể tìm thấy trong thực tế mọi ngôn ngữ chức năng ngoài kia. Bạn gửi một danh sách, một hàm và nó trả về danh sách được tạo thành như sau: (f (l [1]), ..., f (l [n])). – Lasirc