Chowan Temat założony przez niniejszego użytkownika |
odwracajaca kolejnosc el w tablicy, zwalnianie pamieci » 2017-05-18 21:51:24 zadanie z książki, wypełnianie tablicy (do wielkości tablicy lub podania nie liczbowej wartości), wypisanie, odwrócenie elementów i znów wypisanie. Czy da się funkcje odwracającą łatwiej rozpisać, i czy to zwolnienie pamięci delete[]t; jest w dobrym miejscu. chciałem użyć zwykłej tablicy ale wyrzuca błąd "address of local variable 't' returned [-Wreturn-loccal-addr] czyli z tego co się domyślam, że po zakończeniu funkcji pamięć jest zwalniania?? i to wywołuje błąd bo nie ma do czego się odwołać funkcja void show()?? #include <iostream> const int rozm = 10; int fill_array( double * tab, int n ); void show( const double * tab, int n ); double * odw( double * tab, int n ); int main() { using namespace std; double tab[ rozm ]; int a = fill_array( tab, 10 ); show( tab, a ); show( odw( tab, a ), a ); return 0; } int fill_array( double * tab, int n ) { double a; int ile; std::cout << "Podaj liczby, które zostana wpisane do tablicy" << std::endl; for( int i = 0; i < n; i++ ) { if( std::cin >> a ) { tab[ i ] = a; ile++; if( ile > n ) break; } else break; } return ile; } void show( const double * tab, int n ) { std::cout << "tablica zawiera liczby: "; for( int i = 0; i < n; i++ ) { std::cout << tab[ i ] << ", "; } std::cout << std::endl; } double * odw( double * tab, int n ) { int a = n; double * t = new double[ a ]; for( int i = 0; i < n; i++, a-- ) { t[ a - 1 ] = tab[ i ]; } return t; delete[] t; } |
|
karambaHZP |
» 2017-05-18 22:06:21 Zwalnianie pamięci nigdy nie nastąpi, ponieważ wyjście z funkcji jest o linię wcześniej. Zwalnianie powinno znajdować się w miejscu, do którego zwraca się wskaźnik na alokowaną pamięć, gdy już można ją zwolnić. Swoją droga, nie wiem czy dobrze zrozumiałem problem. Chcesz zamienić kolejność elementów w tablicy? (1 2 3 na 3 2 1)? Jeśli tak, nie ma potrzeby alokować nowej pamięci na tablicę. Wystarczy zmienić miejscami elementy. Jeszcze lepiej użyć gotowych narzędzi C++ tj. std::vector i std::reverse z <algorithm>. |
|
Chowan Temat założony przez niniejszego użytkownika |
» 2017-05-18 22:19:00 Dokładnie z 1 2 3 na 3 2 1. A jak to zamienić? Co do Vector i algorithm to nie było tego w książce do tej pory. vector był przedstawiony w sensie co to jest trochę. Co do zwalniania po użyciu to tak chciałem w funkcji main zrobić ale wyskakiwał błąd że to nie jest zadeklarowane in this scope. double * odw( double tab[], int n ) { int a = n; double t[ a ]; for( int i = 0; i < n; i++, a-- ) { t[ a - 1 ] = tab[ i ]; } for( int i = 0; i < n; i++, a-- ) { tab[ i ] = t[ i ]; } return tab; } tak się da, ale to mało elegancko wygląda. |
|
karambaHZP |
» 2017-05-18 23:07:51 o do zwalniania po użyciu to tak chciałem w funkcji main zrobić ale wyskakiwał błąd że to nie jest zadeklarowane in this scope. |
#include <iostream>
int * create_array( std::size_t size ) { int * arr_ptr = new int[ size ]; return arr_ptr; }
void fill_array( int * arr, std::size_t size ) { for( std::size_t i { 0 }; i < size; ++i ) { arr[ i ] = static_cast < int >( i ); } }
int main() { std::size_t size; std::cin >> size; int * arr_ptr_in_main = create_array( size ); fill_array( arr_ptr_in_main, size ); delete[] arr_ptr_in_main; } https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/Jeśli nadal jest potrzeba na new i delete to zerknij: #include <iostream> #include <utility>
void fill_array( int arr[], std::size_t size ) { for( std::size_t i { 0 }; i < size; ++i ) { arr[ i ] = static_cast < int >( i ); } }
void reverese_array( int arr[], std::size_t size ) { std::size_t first { 0 }; std::size_t last { size - 1 }; while( first < last ) { std::swap( arr[ first ], arr[ last ] ); ++first; --last; } }
void print_array( int arr[], std::size_t size ) { for( std::size_t i { 0 }; i < size; ++i ) { std::cout << arr[ i ] << ' '; } std::cout << std::endl; }
int main() { std::size_t size_arr; std::cin >> size_arr; int * arr_ptr = new int[ size_arr ]; fill_array( arr_ptr, size_arr ); print_array( arr_ptr, size_arr ); reverese_array( arr_ptr, size_arr ); print_array( arr_ptr, size_arr ); delete[] arr_ptr; } edit: wersja uproszczona #include <iostream> #include <algorithm> #include <vector>
int main() { std::size_t size; std::cin >> size; std::vector < int > v( size ); int n { 0 }; std::generate( v.begin(), v.end(),[ & ]() { return n++; } ); std::for_each( v.cbegin(), v.cend(),[]( auto const & el ) { std::cout << el << ' '; } ); std::cout << std::endl; std::reverse( v.begin(), v.end() ); std::for_each( v.cbegin(), v.cend(),[]( auto const & el ) { std::cout << el << ' '; } ); } |
|
Chowan Temat założony przez niniejszego użytkownika |
» 2017-05-19 11:23:32 tablica dynamicznie alokowana była mi potrzebna, bo nie widziałem jak inaczej zamienić kolejność, więc chciałem stworzyć nową tablice w środku funkcji i wpisać tam dane w odwrotnej kolejności i wskaźnik do tej nowej tablicy zwrócić. Nie mogłem jej wyrzucić jak była to zwykła tablica a przy dynamicznie alokowanej nie wiedziałem jak usunąć pamieć jak tablica była już nie potrzebna. Bo Twoje przykłady odnoszą się do tablicy "głownej" z która nie było problemu. Natomiast z Twoimi przykładami funkcji swap nie potrzebne mi to(new i delete), zwłaszcza że w tym artykule piszą, że to zły nawyk. W książce Prata to jest często używane (dynamiczna alokacja), natomiast vectory były tylko wspomniane, ale nie używane przynajmniej do tego etapu gdzie jestem, ale poszukam trochę informacji i postaram się używać tych vectorow zamiast new i delete.
Dzięki za prace, którą włożyłeś w wytłumaczenie mi tego. |
|
« 1 » |