W ramach nauki postanowiłem popracować nad implementacją funkcji map. Jest to pierwsza wersja, póki co iteracyjna, bo mam kilka wątpliwości związanych ze zwracanym wskaźnikiem na zaalokowaną pamięć na wyniki. Ok, najpierw kod:
Kod: Zaznacz cały
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
/* typedef funkcji wartosciującej */
typedef int (unaryFuncType)(int obj);
/* Wersja iteracyjna funkcji map. Przyjmuje wskaźnik na kontener, rozmiar kontenera
oraz wskaźnik na funkcję wartosciującą. Zwraca wskaźnik na kontener zawierający efekt pracy
funkcji wartosciującej na każdym elemencie kontenera lub null, gdy nie uda się zaalokować pamięci.*/
int * map_iter(int *src, size_t len, unaryFuncType *fun);
/* Pomocnicza funkcja do pokazywania efektów pracy */
void show_table(int *src, size_t len);
/* Przykladowa funkcja wartosciujaca. Odejmie od kazdego elementu kontenera 511. */
int subtract(int src);
int main(void)
{
int ADC_Samples[] = { 150, 700, 400, 83, 1563, 18, 950, 1234, 37, 0, 44 };
int *ptr;
printf("Zawartosc kontenera przed wywolaniem funkcji map():\n\n");
show_table(ADC_Samples, sizeof(ADC_Samples) / sizeof(ADC_Samples[0]));
ptr = map_iter(ADC_Samples, sizeof(ADC_Samples) / sizeof(ADC_Samples[0]), subtract);
if (ptr != NULL)
{
printf("\nZawartosc kontenera po przejsciu przez map():\n\n");
show_table(ptr, sizeof(ADC_Samples) / sizeof(ADC_Samples[0]));
free(ptr);
}
else
{
printf("Zacznij zbierac znaczki...\n");
}
int key = getchar();
return EXIT_SUCCESS;
}
int * map_iter(int *src, size_t len, unaryFuncType *fun)
{
int *result = (int) malloc(len * sizeof(int));
if (result == NULL)
{
perror("Memory allocation error\n");
return NULL;
}
for (int i = 0; i < len; ++i)
{
result[i] = fun(src[i]);
}
return result;
}
void show_table(int *src, size_t len)
{
for (size_t i = 0; i < len; ++i)
{
printf("Wartosc elementu o indeksie %5d wynosi: %6d\n", i, src[i]);
}
}
int subtract(int src)
{
return src - 511;
}
Przede wszystkim, czy wskaźnik 'result' nie powinien być static? Mam wrażenie, że nie, bo zwracam adres, a nie wartość... Kolejna sprawa to argument formalny int *src w funkcji map_iter. Powinien być const? Wszak nie zmieniam żadnych wartości w kontenerze źródłowym. A może mam zmieniać? Jeśli nie, dopiszę const do tego argumentu. Męczy mnie również fakt, że zwracam jedynie wskaźnik na kontener, a reszta programu nie ma pojęcia o jego wielkości. Tak ma być? No i na koniec zwalnianie pamięci. Wystarczy zwyczajne free(ptr), czy potrzebne są jakieś dodatkowe zabiegi?
Gdyby były jeszcze jakieś błędy, chętnie się o nich dowiem, by je usunąć.