zadanie z szablonów Stephen Prata Szkoła Programowania

0

Zadanie daje oczekujący wynik, jednak nie jest dokońca zrobione zgodnie z poleceniem. Zastanawia mnie jak mogłaby wyglądać w tym przypadku jawna specjalizacja, skoro mamy dwa poziomy przekierowania i w jaki sposób mogę zwolnić pamięć, zaalokowaną w funkcji max() (delete big w funkcji main() nie działa).

Treść zadania: Napisz szablon funkcji maxn() pobierającej jako parametry tablicę typu T oraz liczbę elementów tej tablicy, zwracającej największy element tablicy. Przetestuj w programie 5-elementową tablicę wartości int i 3-elementowa tablice double. Program powinien korzystać ze specjalizacji przyjmującej jako parametr tablicę typu char, zwracającej adres najdłuższego napisu. Jeśli jest kilka najdłuższych łańcuchów, funkcja powinna zwracać adres pierwszego z nich. Sprawdź specjalizację z tablicą pięciu łańcuchów.

#include <iostream>
#include <cstdlib>

using namespace std;

template <typename T> T* maxn(T*, int);
char* max(const char**, int);

int main()
{
    int tab1[5] = {5,4,3,2,1};
    double tab2[4] = {6.7,5.43,20.34,2.1};

    const char* tab3[5] = { "kot", "niedzwiedzica", "chomik", "swinka morska", "pies"}; 

    int* pi = maxn(&tab1[0], 5);
    double* pd = maxn(&tab2[0], 5);

    cout << " Najwieksza liczba (tablica int): " << *pi << endl;
    cout << " Najwieksza liczba (tablica double): " << *pd << endl;

    char* pc = max(&tab3[0], 5);

    cout << " Najdluzszy napis (tablica napisow char) : " << pc;
    
   

    cout << endl;
    cout << endl;

    
    return 0;
}

template <typename T> T* maxn(T* tabe, int x)
{
    int i = 0;
    while (x > 1)
    {
        if (tabe[0] < tabe[i + 1]) // || x=5; i=0 || x=4; i=1 || x=3; i=2 || x=2; i=3 ||    
            tabe[0] = tabe[i + 1];

        x--;
        i++;
    }

    return &tabe[0];

}

char* max(const char** tabe, int x)
{
    char* *big = new char*;

    int n = x;
    int i = x - 1;
    while (n > 1)
    {
        if (strlen((const char*)tabe[i]) <= strlen((const char*)tabe[i - 1]))
            big* = (char*)tabe[i-1];        
        
        n--;
        i--;
    }   

    return big*;
}
1

char **big = new char*; // tu właśnie masz wyciek pamięci
wystarczy:

char *big=nullptr;
...
big=tabe[i-1];
...
return big;

czyli nic nie przydzielasz i nic nie zwalniasz.

0

Dla char to jest u Ciebie overload, nie specjalizacja -- to co innego. Powinno być tak +-:

#include <iostream>
#include <cstdint>
#include <limits>
#include <cstring>
#include <algorithm>

template<typename T, std::size_t N>
T maxn(const T (&arr)[N])
{
    auto max = std::numeric_limits<T>::min();
    for (auto x : arr) {
        max = std::max(x, max);
    }
    return max;
}

template<std::size_t N>
const char* maxn(const char* (&arr)[N])
{
    auto len = 0u;
    const char* max = nullptr;
    for (auto x : arr) {
        max = std::strlen(x) > len ? x : max;
    }
    return max;
}

int main(int, char*[])
{
    int i[] {4,8,10,11,2};
    double d[] {101.2, 5.6, 11.2, 23.8};
    const char* c[] {"Ala", "ma", "kota"};

    std::cout <<  maxn(i) << " " << maxn(d) << " " <<  maxn(c) << "\n";

    return 0;
}

https://godbolt.org/z/qW5G68oah
Pamięci bym w tych templatkach nie tykał, one mają tylko szukać. Ponadto, jeśli przekażesz referencję do tablicy masz bounds-check za darmo.
Ty przekazujesz wskaźniki - to jest delikatnie co innego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1