Nowe posty

xx Dystrybucja pod HP Omen (6)
2024-03-27, 23:30:08
xx [Poradnik] Wyszukiwanie Sterowników (2)
2024-03-27, 21:08:23
lamp Problem z Linux Lite po instalacji (0)
2024-03-27, 19:50:30
xx Ile pingwinów? (1)
2024-03-27, 08:59:24
xx konfiguracja pale moon (0)
2024-03-24, 21:53:42
xx Plasma 6 w Neonie ssie trochę mniej ... (10)
2024-03-23, 02:38:11
xx problem z instalacja sterowników do karty sieciowej (3)
2024-03-18, 18:10:16
xx Plik abc.001 (1)
2024-03-17, 17:48:27
xx Zlecę dopracowanie programu w MatLab (0)
2024-03-13, 15:28:40
xx Linux Mint 21.3 XFCE brak dźwieku po paru minutach (karta muzyczna zintegrowana) (5)
2024-03-12, 23:07:01

Autor Wątek: wskaźnik do funkcji nie chce się wywołąć  (Przeczytany 2875 razy)

KelThuzad

  • Gość
wskaźnik do funkcji nie chce się wywołąć
« dnia: 2016-05-13, 17:11:24 »
Witam mam problem bo program nie che się z kompilować przez takie dwie linijki pointer_size_tab = &what_size_tab; i pointer_size_tab2 = &what_size_tab2; dodam że what_size_tab i what_size_tab2 to funkcji. W symfonii C++ jest tak że wskaźnik = &nazwa_funkcji lub wskaźnik = nazwa_funkcji ale u mnie nie wiem czemu żadne z tych rozwiązań nie działa.

#include <iostream>
#include <stdlib.h>

using namespace std;

//int size_tab;
//int size_tab2;

int *pointer_size_tab = new int;
int *pointer_size_tab2 = new int;

int *pointer_tab = new int[*pointer_size_tab];                                                                           //pod wskaznikiem wsk_tab jest tablica z odpowiednim rozmiarem
int *pointer_tab2 = new int[*pointer_size_tab2];                                                                         //pod wskaznikiem wsk_tab2 jest tablica z odpowiednim rozmiarem

int what_size_tab/*jaki rozmiar tablicy*/( int k );
int what_size_tab2/*jaki rozmiar tablicy*/( int k );
void assignment/*przypisanie*/( int *pointer_size_tab , int *pointer_size_tab2 , int k , int *pointer_tab , int *pointer_tab2 );
int compare/*porównaie*/( int *pointer_size_tab , int *pointer_size_tab2 );                                     //pointer(ang) == wskaźnik(pl)
void tab_sum_tab2/*sumowanie tab i tab2*/( int result_compare_size , int *pointer_tab , int *pointer_tab2 );

int main()
{
    int result_compare_size;

    for ( int k = 0 ; k < 2 ; k++)
    {
        if ( k == 0)
        {
            //size_tab = what_size_tab( k );
            pointer_size_tab = &what_size_tab;
            cout << "rozmiar tablicy " << k+1 << " to " << *pointer_size_tab << endl;
            //cout << "Wskaznik ma wartość " << size_tab << endl;
            assignment( pointer_size_tab , pointer_size_tab2 , k , pointer_tab , pointer_tab2 );
        }
        else if ( k == 1 )
        {
            //size_tab2 = what_size_tab2( k );
            pointer_size_tab2 = &what_size_tab2;
            cout << "rozmiar tablicy " << k+1 << " to " << pointer_size_tab2 << endl;
            //cout << "Wskaznik ma wartość " << size_tab2 << endl;
            assignment( pointer_size_tab , pointer_size_tab2 , k , pointer_tab , pointer_tab2);
        }
    }
    result_compare_size = compare/*porównaie*/( pointer_size_tab , pointer_size_tab2 );
    cout << "wspolny rozmiar tablic to " << result_compare_size << endl;

    system("clear");

    tab_sum_tab2/*sumowanie tab i tab2*/( result_compare_size , pointer_tab , pointer_tab2 );
    return 0;
}

//***************************************************************************

int what_size_tab/*jaki rozmiar tablict*/( int k )
{
    int size = 0;
    cout << "Podaj rozmiar tablicy " << k+1 << " ";
    cin >> size;
    return size;
}

//***************************************************************************

int what_size_tab2/*jaki rozmiar tablicy*/( int k )
{
    int size1 = 0;
    cout << "Podaj rozmiar tablicy " << k+1 << " ";
    cin >> size1;
    return size1
            ;
}

//***************************************************************************

void assignment/*przypisanie*/( int *pointer_size_tab , int *pointer_size_tab2 , int k , int *pointer_tab , int *pointer_tab2 )
{
    //cout << "\nK wynosi: " << k << "\n" << endl;
    int number;

    if ( k == 0)
    {
        for ( int i = 0 ; i < *pointer_size_tab ; i++)
        {
            cin >> number;
            pointer_tab[i] = number;
            cout << "tab[" << i << "] = " << pointer_tab[i] << endl;
        }
    }
    else if( k == 1)
    {
        for ( int i = 0 ; i < *pointer_size_tab2 ; i++)
        {
            cin >> number;
            pointer_tab2[i] = number;
            cout << "tab[" << i << "] = " << pointer_tab2[i] << endl;
        }
    }
}

//***************************************************************************

int compare/*porównanie*/( int *pointer_size_tab , int *pointer_size_tab2 )
{
    //cout << "rozmiar 1 tablicy " << *pointer_size_tab << " rozmiar 2 tablicy " << *pointer_size_tab2 << endl;

    if (*pointer_size_tab2 > *pointer_size_tab)
    {
        //cout << "\nwartość pointer_size_tab opcja1 " << *pointer_size_tab << "\n" << endl;
        return *pointer_size_tab;
    }
    else if (*pointer_size_tab > *pointer_size_tab2)
    {
        //cout << "\nwartość pointer_size_tab opcja2 " << *pointer_size_tab2 << "\n" << endl;
        return *pointer_size_tab2;
    }
    else
    {
        //cout << "\nwartość pointer_size_tab opcja3 " << *pointer_size_tab << "\n" << endl;
        return *pointer_size_tab;
    }
}

//**************************************************************************

void tab_sum_tab2/*sumowanie tab i tab2*/( int result_compare_size , int *pointer_tab , int *pointer_tab2 )
{
    int result_sum = 0;

    for ( int i = 0 ; i < result_compare_size ; i++ )
    {
        result_sum = pointer_tab[i] + pointer_tab2[i];

        cout << "sumowanie " << result_sum << endl;
        cout << "wastość tab 1 " << *pointer_tab << "wartosc tab2 " << *pointer_tab2 << endl;

        cout << "\ntab[" << i << "](" << *(pointer_tab++) << ") + tab2[" << i << "](" << *(pointer_tab2++) << ") = tab3[" << i << "](" << result_sum << ")" << endl;
    }
}

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #1 dnia: 2016-05-13, 18:27:39 »
Ale masz WSZYSTKO w komunikacie błędu:
main.cpp:30: error: cannot convert 'int (*)(int)' to 'int*' in assignment
             pointer_size_tab = &what_size_tab;
                              ^
w kontekście
int *pointer_size_tab = new int; // <- to jest wskaźnik na INT
int what_size_tab( int k ); // <- to jest funkcja

/*30*/ pointer_size_tab = &what_size_tab; // Nie możesz przypisać wskaźnika do funkcji do wskaźnika do int. To są różne typy.

Mam wrażenie, że chciałeś zrobić
   *pointer_size_tab = what_size_tab( k ); // Przypisz do komórki wskazywanej przez wskaźnik wynik działania funkcji.
« Ostatnia zmiana: 2016-05-13, 18:31:27 wysłana przez Paweł Kraszewski »
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

KelThuzad

  • Gość
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #2 dnia: 2016-05-13, 19:23:33 »
Dzięki wielkie ale mam jeszcze jeden problem przy funkcji sumowania dobrze sumuje mi tylko tab[0] i tab2[0] a później są cyrki.

OK już doszedłem do tego co robiłem źle kod który już działa wygląda tak:

#include <iostream>
#include <stdlib.h>

using namespace std;

int what_size_tab/*jaki rozmiar tablicy*/( int k );
int what_size_tab2/*jaki rozmiar tablicy*/( int k );
void assignment/*przypisanie*/( int *pointer_size_tab , int *pointer_size_tab2 , int k , int *pointer_tab , int *pointer_tab2 );
int compare/*porównaie*/( int *pointer_size_tab , int *pointer_size_tab2 );                                     //pointer(ang) == wskaźnik(pl)
void tab_sum_tab2/*sumowanie tab i tab2*/( int result_compare_size , int *pointer_tab , int *pointer_tab2 );

int main()
{
    int *pointer_size_tab = new int;
    int *pointer_size_tab2 = new int;
    int *pointer_tab = new int[*pointer_size_tab];                                                                           //pod wskaznikiem wsk_tab jest tablica z odpowiednim rozmiarem
    int *pointer_tab2 = new int[*pointer_size_tab2];                                                                         //pod wskaznikiem wsk_tab2 jest tablica z odpowiednim rozmiarem
    int result_compare_size;

    for ( int k = 0 ; k < 2 ; k++)
    {
        if ( k == 0)
        {
            *pointer_size_tab = what_size_tab( k );
            cout << "rozmiar tablicy " << k+1 << " to " << *pointer_size_tab << endl;
            assignment( pointer_size_tab , pointer_size_tab2 , k , pointer_tab , pointer_tab2 );
            system("clear");
        }
        else if ( k == 1 )
        {
            *pointer_size_tab2 = what_size_tab2( k );
            cout << "rozmiar tablicy " << k+1 << " to " << *pointer_size_tab2 << endl;
            assignment( pointer_size_tab , pointer_size_tab2 , k , pointer_tab , pointer_tab2);
            system("clear");
        }
    }
    result_compare_size = compare/*porównaie*/( pointer_size_tab , pointer_size_tab2 );
    system("clear");
    tab_sum_tab2/*sumowanie tab i tab2*/( result_compare_size , pointer_tab , pointer_tab2 );
    return 0;
}

//***************************************************************************

int what_size_tab/*jaki rozmiar tablict*/( int k )
{
    int size = 0;
    cout << "Podaj rozmiar tablicy " << k+1 << " ";
    cin >> size;
    return size;
}

//***************************************************************************

int what_size_tab2/*jaki rozmiar tablicy*/( int k )
{
    int size1 = 0;
    cout << "Podaj rozmiar tablicy " << k+1 << " ";
    cin >> size1;
    return size1;
}

//***************************************************************************

void assignment/*przypisanie*/( int *pointer_size_tab , int *pointer_size_tab2 , int k , int *pointer_tab , int *pointer_tab2 )
{
    int number;

    if ( k == 0)
    {
        for ( int i = 0 ; i < *pointer_size_tab ; i++)
        {
            cin >> number;
            pointer_tab[i] = number;
            cout << "tab[" << i << "] = " << pointer_tab[i] << endl;
        }
    }
    else if( k == 1)
    {
        for ( int i = 0 ; i < *pointer_size_tab2 ; i++)
        {
            cin >> number;
            pointer_tab2[i] = number;
            cout << "tab[" << i << "] = " << pointer_tab2[i] << endl;
        }
    }
}

//***************************************************************************

int compare/*porównanie*/( int *pointer_size_tab , int *pointer_size_tab2 )
{
    if (*pointer_size_tab2 > *pointer_size_tab)
    {
        return *pointer_size_tab;
    }
    else if (*pointer_size_tab > *pointer_size_tab2)
    {
        return *pointer_size_tab2;
    }
    else
    {
        return *pointer_size_tab;
    }
}

//**************************************************************************

void tab_sum_tab2/*sumowanie tab i tab2*/( int result_compare_size , int *pointer_tab , int *pointer_tab2 )
{
    int result_sum = 0;

    for ( int i = 0 ; i < result_compare_size ; i++ )
    {
        result_sum = pointer_tab[i] + pointer_tab2[i];
        cout << "\ntab[" << i << "](" << pointer_tab[i] << ") + tab2[" << i << "](" << pointer_tab2[i] << ") = tab3[" << i << "](" << result_sum << ")" << endl;
    }
}
« Ostatnia zmiana: 2016-05-13, 20:53:22 wysłana przez MateuszA »

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #3 dnia: 2016-05-14, 10:07:31 »
Tutaj masz zasadniczy błąd koncepcyjny - miałem nadzieję, że jak skompilujesz program to sam do tego dojdziesz:

1. Program wykonywany jest w kolejności występowania linii w bloku (to jest zadziwiająco nieoczywiste dla początkujących)
2. Tablice tworzone przez new T[ x ] mają stały rozmiar

Masz teraz taką (uproszczoną) sekwencję linii:
int *pointer_size_tab = new int;
int *pointer_tab = new int[*pointer_size_tab];

/*
 kawał programu
*/

*pointer_size_tab = what_size_tab( k );

a teraz to samo z komentarzem:
int *pointer_size_tab = new int;
/*
  pointer_size_tab jest wskaźnikiem na nowo stworzoną
  zmienną typu int o wartości 0 (bo new czyści allokowaną pamięć)
*/

int *pointer_tab = new int[*pointer_size_tab];
/*
 pointer_tab jest wskaźnikiem na statycznie rozmiarowaną
 tablicę int-ów o rozmiarze *pointer_size_tab (czyli 0).
 Jest to poprawna operacja w C++, zwraca poprawny adres
 tablicy o rozmiarze 0 elementów (punkt 5.3.4/7 standardu)
 Obiekt taki można tylko usunąć przez delete.
 Obiektu nie można użyć (dereferencja tablicy [0] jest
 operacją niezdefiniowaną według punktu 3.7.3.1/2
 standardu)
*/

*pointer_size_tab = what_size_tab( k );
/*
 Przypisuje nową wartość do zmiennej wskazywanej przez
 pointer_size_tab.
 =========
 W ŻADEN SPOSÓB nie zmienia to rozmiaru tablicy już
 zaalokowanej w poprzedniej linii, nawet jeżeli jej rozmiar
 był pobrany spod *pointer_size_tab
 =========
*/

1/ Niesamowicie męczące w czytaniu jest wbijanie komentarzy między
nazwę funkcji a parametry. Dawaj je albo linię przed, albo linię po, albo na końcu linii.

2/ Nigdy nie dawaj komentarzy do spraw oczywistych: compare/*porównaie*/( pointer_size_tab , pointer_size_tab2 ). Czemu to ma służyć?
« Ostatnia zmiana: 2016-05-14, 10:10:23 wysłana przez Paweł Kraszewski »
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

KelThuzad

  • Gość
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #4 dnia: 2016-05-15, 21:28:38 »
Wiesz co dopiero się uczę. Jak zrozumiałem dobrze to chodzi ci o to że

int *pointer_tab = new int[*pointer_size_tab];

powinienem zadeklarować gdzieś po

*pointer_size_tab = what_size_tab( k );

Ale nie jestem pewny czy o to ci chodzi. Ale dlaczego ten program działa?

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #5 dnia: 2016-05-16, 08:20:07 »
Wiesz co dopiero się uczę. Jak zrozumiałem dobrze to chodzi ci o to że (ciach) powinienem zadeklarować gdzieś po (ciach)

Ale nie jestem pewny czy o to ci chodzi. Ale dlaczego ten program działa?

1. Dokładnie o to chodzi. Jakbym napisał wprost, to byś się nad tym nie zastanawiał i nie doszedł sam do rozwiązania.

W moim przypadku "dlaczego" jest niebezpiecznym pytaniem, bo można uzyskać dużo więcej wiedzy niż się pierwotnie chciało...

2. Działa przez to, że mimo że tablica logicznie ma rozmiar zero, to nie da się zrobić tablicy o fizycznym rozmiarze 0 (dodatkowo, wspomniany w pierwszym moim poście standard mówi, że new int[0] ma zwracać różne adresy dla kolejnych wywołań).

W wersji z Twojego ostatniego posta (czyli "z błędem") dodaj między int result_compare_size; a pierwszym for-em to:
    int roznica = (char*)pointer_tab2 - (char*)pointer_tab;
    cout << "adres pointer_tab:\t" << pointer_tab << endl;
    cout << "adres pointer_tab2:\t" << pointer_tab2 << endl;
    cout << "różnica adresów w bajtach:\t" << roznica << endl;
    cout << "rozmiar int-a w bajtach:\t"<<sizeof(int)<<endl;
    cout << "tyle int-ów zmieści się w tablicy o rozmiarze 0:\t"
         << roznica/sizeof(int)  << endl;

U mnie - kompilator CLANG w wersji 3.8.0-2ubuntu3 - wynik generowany przez te linijki wygląda tak (z czego adresy pointer_tab-ów są za każdym razem inne, ze względu na randomizację adresów, ale ich różnica jest stała):
adres pointer_tab:	0x9d3c60
adres pointer_tab2: 0x9d3c80
różnica adresów w bajtach: 32
rozmiar int-a w bajtach: 4
tyle int-ów zmieści się w tablicy o rozmiarze 0: 8

Skąd to wynika? Połączenie 2 czynników:
a) Generalnie, współczesne systemy po prostu operują w pamięci w kawałkach po 16 bajtów. Jest to połączenie zaszłości ze starego x86, gdzie 16 bajtów to była różnica adresów dwóch kolejnych segmentów (czasami wygodniej było adresować tablicę od początku segmentu) i tego, że nowe procesory mają "ścieżkę danych" o długości 128bitów (czyli właśnie 16 bajtów) i wiele operacji wykonywanych jest szybciej, jeżeli adres jest podzielny przez 16.
b) No dobra, strona, 16bajtów - ale różnica jest 32? Tak. To 32 bajty składa się z dwóch 16-bajtowych kawałków:
 * 16 bajtów tuż przed adresem wskaźnika (czyli w moim przykładzie od adresów 0x9d3c50 i 0x9d3c70) to są wewnętrzne dane allokatora pamięci. Na przykład informacja czy było to new czy new[] i temu podobna księgowość. Nie jest to udokumentowane i normalny użytkownik nie musi tego wiedzieć. Ja nie wiem i jeszcze NIGDY nie było mi to potrzebne.
 * 16 bajtów od adresu wskaźnika to miejsce na Twoje dane. Najmniejszą paczką jest 16 bajtów - więc nawet jak zażądasz mniej, to i tak dostaniesz 16.

Czyli w rzeczywistości mapa pamięci tego kawałka wygląda tak:
0x9d3c50 - 16 bajtów księgowości pointer_tab
0x9d3c60 - 16 bajtów na dane przechowywane w pointer_tab
0x9d3c70 - 16 bajtów księgowości pointer_tab2
0x9d3c80 - 16 bajtów na dane przechowywane w pointer_tab2
Twoj program nie korzysta z delete (bad thing!), więc zasadniczo bajty księgowości nie są używane. W związku z tym dostajesz "za darmo" dodatkowe 16 bajtów tablicy. Dlatego program powinien "poprawnie" działać do tablic o rozmiarze 8 włącznie. Od rozmiaru 9 wczytywanie tablicy 2 zacznie wchodzić w interakcję z tablicą 1.

Zainstaluj sobie program valgrind i uruchom swój kod pod jego kontrolą. U mnie pokazał wszystkie błędy - i operacje na tablicach[0] (błąd is 0 bytes after a block of size 0 alloc'd)
dużo błędów tego typu...

==19242== Invalid read of size 4
==19242==    at 0x401103: tab_sum_tab2(int, int*, int*) (main.cpp:126)
==19242==    by 0x400DF3: main (main.cpp:57)
==19242==  Address 0x5ab5d20 is 0 bytes after a block of size 0 alloc'd
==19242==    at 0x4C2E80F: operator new[](unsigned long)
==19242==    by 0x400B2D: main (main.cpp:21)

dużo błędów tego typu...
i brak zwolnienia pamięci:
==19328== 0 bytes in 1 blocks are definitely lost in loss record 1 of 5
==19328==    at 0x4C2E80F: operator new[](unsigned long)
==19328==    by 0x400B2D: main (main.cpp:21)
==19328==
==19328== 0 bytes in 1 blocks are definitely lost in loss record 2 of 5
==19328==    at 0x4C2E80F: operator new[](unsigned long)
==19328==    by 0x400B5E: main (main.cpp:24)
==19328==
==19328== 4 bytes in 1 blocks are definitely lost in loss record 3 of 5
==19328==    at 0x4C2E0EF: operator new(unsigned long)
==19328==    by 0x400AED: main (main.cpp:19)
==19328==
==19328== 4 bytes in 1 blocks are definitely lost in loss record 4 of 5
==19328==    at 0x4C2E0EF: operator new(unsigned long)
==19328==    by 0x400AFD: main (main.cpp:20)
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #6 dnia: 2016-05-16, 11:10:53 »
Normalnie tego nie robię, ale uczysz się (i chcesz się uczyć):
#include <iostream>

using namespace std;

/*
 * Uwaga! Napisy zdefiniowane w kodzie w "cudzysłowach"
 * są typu "const char*" a nie "char *", dlatego w funkcjach
 * parametry mają właśnie taki typ.
 */

/**
 * @brief wczytaj_tablice wczytuje tablicę o podanym rozmiarze
 *           pod wskazany adres.
 * @param poczatek adres początku tablicy do wypełnienia
 * @param nazwa napis wyświetlany przy indeksie wczytywanych danych
 * @param dlugosc długość przygotowanej tablicy
 */
void wczytaj_tablice( int *poczatek, const char *nazwa, int dlugosc );

/**
 * @brief dodaj_tablice sumuje 2 tablice wyświetlając wynik na bieżąco.
 * @param t1 adres pierwszej tablicy
 * @param n1 nazwa pierwszej tablicy
 * @param t2 adres drugiej tablicy
 * @param n2 nazwa drugiej tablicy
 * @param dlugosc długość obu tablic
 */
void dodaj_tablice( int *t1, const char *n1, int *t2, const char *n2,
                    int dlugosc );

/**
 * @brief main główna procedura programu
 * @return kod błędu (u nas zawsze 0)
 */
int main()
{
    int *tablica1;
    int *tablica2;
    int  rozmiar;

    /* Wczytanie rozmiaru tablic */
    cout << "Podaj rozmiar tablic: ";
    cin >> rozmiar;

    /* Allokacja i wczytanie zawartości tablicy 1 */
    tablica1 = new int[rozmiar];
    wczytaj_tablice( tablica1, "T1", rozmiar );

    /* Allokacja i wczytanie zawartości tablicy 2 */
    tablica2 = new int[rozmiar];
    wczytaj_tablice( tablica2, "T2", rozmiar );

    /* Sumowanie zawartości tablic */
    dodaj_tablice( tablica1, "T1", tablica2, "T2", rozmiar );

    /*
     * Zwolnienie zaalokowanej pamięci.
     * Użyto delete[] bo było new[]
     * Nie wolno tego mieszać.
     */
    delete[]( tablica1 );
    delete[]( tablica2 );

    /* Zgłoszenie systemowi operacyjnemu poprawnego zakończenia */
    return 0;
}

/* *********************************************************
 *
 * Normalnie poniższe linijki byłyby w osobnym pliku .c/.cpp
 * a nie duplikuje się dokumentacji (bo po kilku poprawkach
 * i tak się rozjedzie z dokumentacją z góry).
 *
 * *********************************************************/

/* ********************************************************************* */

void wczytaj_tablice( int *poczatek, const char *nazwa, int dlugosc )
{
    for( int i = 0; i < dlugosc; i++ ) {
        cout << nazwa << "[" << i << "]=";
        cin >> poczatek[i];
    }
    /*
     * Dodanie pustej linii po ostatnim wczytanym elemencie,
     * żeby użytkownik mógł zauważyć, że wczytujemy następną
     * tablicę.
     */
    cout << endl;
}

/* ********************************************************************* */

void dodaj_tablice( int *t1, const char *n1, int *t2, const char *n2,
                    int dlugosc )
{
    for( int i = 0; i < dlugosc; i++ ) {
        cout << n1 << "[" << i << "] + " << n2 << "[" << i << "] = ";
        cout << t1[i] << " + " << t2[i] << " = " << t1[i] + t2[i];
        cout << endl;
    }
}

Oczywiście program można napisać inaczej/lepiej, ale to co jest wyżej wykorzystuje tylko co już znasz.

Wynik Valgrind:
#> valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all ./forum01

==7007== Memcheck, a memory error detector
==7007== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7007== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==7007== Command: ./forum01
==7007==
Podaj rozmiar tablic: 5
T1[0]=1
T1[1]=2
T1[2]=3
T1[3]=4
T1[4]=5

T2[0]=8
T2[1]=7
T2[2]=6
T2[3]=5
T2[4]=4

T1[0] + T2[0] = 1 + 8 = 9
T1[1] + T2[1] = 2 + 7 = 9
T1[2] + T2[2] = 3 + 6 = 9
T1[3] + T2[3] = 4 + 5 = 9
T1[4] + T2[4] = 5 + 4 = 9
==7007==
==7007== HEAP SUMMARY:
==7007==     in use at exit: 72,704 bytes in 1 blocks
==7007==   total heap usage: 5 allocs, 4 frees, 74,792 bytes allocated
==7007==
==7007== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==7007==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7007==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==7007==    by 0x40104E9: call_init.part.0 (dl-init.c:72)
==7007==    by 0x40105FA: call_init (dl-init.c:30)
==7007==    by 0x40105FA: _dl_init (dl-init.c:120)
==7007==    by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==7007==
==7007== LEAK SUMMARY:
==7007==    definitely lost: 0 bytes in 0 blocks
==7007==    indirectly lost: 0 bytes in 0 blocks
==7007==      possibly lost: 0 bytes in 0 blocks
==7007==    still reachable: 72,704 bytes in 1 blocks
==7007==         suppressed: 0 bytes in 0 blocks
==7007==
==7007== For counts of detected and suppressed errors, rerun with: -v
==7007== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
(72704 bajtów "still reachable" jest z samego Valgrinda i nie mamy na to wpływu)
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

KelThuzad

  • Gość
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #7 dnia: 2016-05-16, 19:39:30 »
Bardzo, Bardzo Ci dziękuje za pomoc Pawle dzięki tobie już lepiej łapie gdzie deklarować wskaźniki (ale jeszcze kawał książki przede mną) zaraz poprawie swój program i sprawdzę go na większych rozmiarach tablic. Później skompiluje i przestudiuje twój program. Jeszcze raz dziękuje.

u mnie valgrind daje coś takiego.
valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all ./main.cpp
==29160== Memcheck, a memory error detector
==29160== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==29160== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==29160== Command: ./main.cpp
==29160==
./main.cpp: 4: ./main.cpp: using: not found
./main.cpp: 6: ./main.cpp: Syntax error: "(" unexpected
==29160==
==29160== HEAP SUMMARY:
==29160==     in use at exit: 1,224 bytes in 70 blocks
==29160==   total heap usage: 75 allocs, 5 frees, 3,264 bytes allocated
==29160==
==29160== 16 bytes in 1 blocks are still reachable in loss record 1 of 4
==29160==    at 0x482A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29160==    by 0x1140CA: ??? (in /bin/dash)
==29160==    by 0x11B2FD: ??? (in /bin/dash)
==29160==    by 0x11BD98: ??? (in /bin/dash)
==29160==    by 0x10AD6F: main (in /bin/dash)
==29160==
==29160== 66 bytes in 1 blocks are still reachable in loss record 2 of 4
==29160==    at 0x482A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29160==    by 0x48D59C7: strdup (strdup.c:42)
==29160==    by 0x11414A: ??? (in /bin/dash)
==29160==    by 0x10C179: ??? (in /bin/dash)
==29160==    by 0x11BDC3: ??? (in /bin/dash)
==29160==    by 0x10AD6F: main (in /bin/dash)
==29160==
==29160== 70 bytes in 1 blocks are still reachable in loss record 3 of 4
==29160==    at 0x482A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29160==    by 0x1140CA: ??? (in /bin/dash)
==29160==    by 0x11B3E6: ??? (in /bin/dash)
==29160==    by 0x10C1C0: ??? (in /bin/dash)
==29160==    by 0x11BDC3: ??? (in /bin/dash)
==29160==    by 0x10AD6F: main (in /bin/dash)
==29160==
==29160== 1,072 bytes in 67 blocks are still reachable in loss record 4 of 4
==29160==    at 0x482A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==29160==    by 0x1140CA: ??? (in /bin/dash)
==29160==    by 0x11B2FD: ??? (in /bin/dash)
==29160==    by 0x11BD53: ??? (in /bin/dash)
==29160==    by 0x10AD6F: main (in /bin/dash)
==29160==
==29160== LEAK SUMMARY:
==29160==    definitely lost: 0 bytes in 0 blocks
==29160==    indirectly lost: 0 bytes in 0 blocks
==29160==      possibly lost: 0 bytes in 0 blocks
==29160==    still reachable: 1,224 bytes in 70 blocks
==29160==         suppressed: 0 bytes in 0 blocks
==29160==
==29160== For counts of detected and suppressed errors, rerun with: -v
==29160== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
« Ostatnia zmiana: 2016-05-16, 22:00:43 wysłana przez MateuszA »

KelThuzad

  • Gość
Odp: wskaźnik do funkcji nie chce się wywołąć
« Odpowiedź #8 dnia: 2016-05-16, 22:08:32 »
tak zmieniłem program
#include <iostream>
#include <stdlib.h>

using namespace std;

int what_size_tab/*jaki rozmiar tablicy*/( int k );
int what_size_tab2/*jaki rozmiar tablicy*/( int k );
void assignment/*przypisanie*/( int *pointer_size_tab , int *pointer_size_tab2 , int k , int *pointer_tab , int *pointer_tab2 );
int compare/*porównaie*/( int *pointer_size_tab , int *pointer_size_tab2 );                                     //pointer(ang) == wskaźnik(pl)
void tab_sum_tab2/*sumowanie tab i tab2*/( int result_compare_size , int *pointer_tab , int *pointer_tab2 );

int main()
{
    int *pointer_size_tab = new int;
    int *pointer_size_tab2 = new int;
    int *pointer_tab;
    int *pointer_tab2;
//    int *pointer_tab = new int[*pointer_size_tab];                                                                           //pod wskaznikiem wsk_tab jest tablica z odpowiednim rozmiarem
//    int *pointer_tab2 = new int[*pointer_size_tab2];                                                                         //pod wskaznikiem wsk_tab2 jest tablica z odpowiednim rozmiarem
    int result_compare_size;

    for ( int k = 0 ; k < 2 ; k++)
    {
        if ( k == 0)
        {
            *pointer_size_tab = what_size_tab( k );
            pointer_tab = new int[*pointer_size_tab];
            cout << "rozmiar tablicy " << k+1 << " to " << *pointer_size_tab << endl;
            assignment( pointer_size_tab , pointer_size_tab2 , k , pointer_tab , pointer_tab2 );
            system("clear");
        }
        else if ( k == 1 )
        {
            *pointer_size_tab2 = what_size_tab2( k );
            pointer_tab2 = new int[*pointer_size_tab2];
            cout << "rozmiar tablicy " << k+1 << " to " << *pointer_size_tab2 << endl;
            assignment( pointer_size_tab , pointer_size_tab2 , k , pointer_tab , pointer_tab2);
            system("clear");
        }
    }
    result_compare_size = compare/*porównaie*/( pointer_size_tab , pointer_size_tab2 );
    system("clear");
    tab_sum_tab2/*sumowanie tab i tab2*/( result_compare_size , pointer_tab , pointer_tab2 );
    delete[] pointer_tab;
    delete[] pointer_tab2;
    return 0;
}

//***************************************************************************

int what_size_tab/*jaki rozmiar tablict*/( int k )
{
    int size = 0;
    cout << "Podaj rozmiar tablicy " << k+1 << " ";
    cin >> size;
    return size;
}

//***************************************************************************

int what_size_tab2/*jaki rozmiar tablicy*/( int k )
{
    int size1 = 0;
    cout << "Podaj rozmiar tablicy " << k+1 << " ";
    cin >> size1;
    return size1;
}

//***************************************************************************

void assignment/*przypisanie*/( int *pointer_size_tab , int *pointer_size_tab2 , int k , int *pointer_tab , int *pointer_tab2 )
{
    int number;

    if ( k == 0)
    {
        for ( int i = 0 ; i < *pointer_size_tab ; i++)
        {
            cin >> number;
            pointer_tab[i] = number;
            cout << "tab[" << i << "] = " << pointer_tab[i] << endl;
        }
    }
    else if( k == 1)
    {
        for ( int i = 0 ; i < *pointer_size_tab2 ; i++)
        {
            cin >> number;
            pointer_tab2[i] = number;
            cout << "tab[" << i << "] = " << pointer_tab2[i] << endl;
        }
    }
}

//***************************************************************************

int compare/*porównanie*/( int *pointer_size_tab , int *pointer_size_tab2 )
{
    if (*pointer_size_tab2 > *pointer_size_tab)
    {
        return *pointer_size_tab;
    }
    else if (*pointer_size_tab > *pointer_size_tab2)
    {
        return *pointer_size_tab2;
    }
    else
    {
        return *pointer_size_tab;
    }
}

//**************************************************************************

void tab_sum_tab2/*sumowanie tab i tab2*/( int result_compare_size , int *pointer_tab , int *pointer_tab2 )
{
    int result_sum = 0;

    for ( int i = 0 ; i < result_compare_size ; i++ )
    {
        result_sum = pointer_tab[i] + pointer_tab2[i];
        cout << "\ntab[" << i << "](" << pointer_tab[i] << ") + tab2[" << i << "](" << pointer_tab2[i] << ") = tab3[" << i << "](" << result_sum << ")" << endl;
    }
}

I mam jeszcze jedno pytanie w Symfonii C++ doszedłem do klas i mam pytanie (bo mam pomysł jak zmienić tan program na klasy) ale czy to jest opłacalne?? (czy do tego są klasy).
« Ostatnia zmiana: 2016-05-16, 22:23:25 wysłana przez MateuszA »