• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Tablica wskaźników na wskaźniki na klasę...

Object Storage Arubacloud
0 głosów
707 wizyt
pytanie zadane 25 stycznia 2016 w C i C++ przez Łukasz Wasilewski Mądrala (5,190 p.)

Proste pytanie.

Jeśli tworzę tablicę w klasie:

class kopiec
{
private:
	element *min, *maks;
	element **tablica[];

public:
	kopiec(void);
	~kopiec(void);

	void addNew(element*);
};

 A jej wielkość jest różna:

tablica[iloscPoziomow][2^iloscPoziomow]

tj. korzenia (0) -> 1

poziom 1 -> 2

poziom 3 -> 8

itd...

 

Zeruje tablice ze "śmieci" za każdym razem gdy dodaje poziom. 

Właściwe pytanie:

Czy mój program nie czyści jakiś potrzebnych danych innego programu? To są przecież tablica wskaźników na wskaźniki czyli nie wyczyszczone przypadkowe dane z komórek pamięci.. Jak procesor szuka miejsca dla tej tablicy? Czy jeśli ta tablica nie jest określona jakąś stałą wielkością, to czy podczas działania mojego programu inny program może sobie też wyczyścić jakąś daną z mojej tablicy?

Jeszcze jedno: Czy tworzenie takich tablic to dobra praktyka? Czy raczej nie powinno się tak robić? 

3 odpowiedzi

+1 głos
odpowiedź 25 stycznia 2016 przez Patrycjerz Mędrzec (192,320 p.)

Chodzi ci o dynamiczną tablicę, stworzoną za pomocą new? Tutaj wskaźnik jest tylko potrzebny do przechowania adresu pierwszego elementu danego wymiaru - taki swoisty punkt odniesienia. Jeśli zaalokujesz pamieć za pomocą new, będzie ona zajęta aż do zwolnienia jej za pomocą delete lub do zakończenia procesu, w którym była zajęta.

komentarz 25 stycznia 2016 przez Łukasz Wasilewski Mądrala (5,190 p.)
Nie, nie. Mam na myśli, że nie znam ani nie podaje rozmiaru tej tablicy. Raz mam element na pozycji [2][4] a raz [122][3000]. Tylko że nie deklarowałem elementu [2][3000], więc drugi element (ten na pozycji [2][3000]) ma się nijak do adresu pierwszego elementu tablicy.. Bo jeżeli nie podaje drugiej wielkości tablicy [][tej] to jaką ilość miejsca zarezerwuje procesor dla mojej tablicy? [3000]? A dodam kolejny poziom i tam będzie [200][56000], to czy powstanie miejsce na [0][56000], a pozostałe elementy [1][0] przesunie o kilkadziesiąt tysięcy miejsc w pamięci? Wydaje mi się że procesor robi to inaczej.
komentarz 25 stycznia 2016 przez draghan VIP (106,230 p.)

Nie, nie. Mam na myśli, że nie znam ani nie podaje rozmiaru tej tablicy.

Eeeee... Skoro nie podajesz rozmiaru tablicy, to nie ma prawa działać. ;) Musisz skorzystać (do wyboru):
1) z tablicy statycznej, gdzie wielkość określasz na etapie kompilacji, explicite w kodzie:

int tab[3][4];


2) z tablicy dynamicznej, gdzie deklarujesz jedynie odpowiedni wskaźnik i za pomocą operatora new prosisz system operacyjny, żeby udostępnił Ci pamięć:
 

int **tab;
tab = new int*[3];
for(unsigned i = 0; i < 3; ++i)
  tab[i] = new int[4];


3) z odpowiedniego kontenera, udostępnionego przez bibliotekę standardową, najbardziej popularny jest chyba vector, ale jest cała masa innych:
 

#include <vector>
// ...
std::vector <vector<int>> tab;

 

+1 głos
odpowiedź 25 stycznia 2016 przez Dash Nałogowiec (29,650 p.)

Czy tworzenie takich tablic to dobra praktyka? Czy raczej nie powinno się tak robić? 

To zależy jak bardzo nienawidzisz współpracownika/programisty który będzie musiał z twojego kodu korzystać. Wskaźnik, na wskaźnik na klasę troszeczkę, że tak powiem, komplikuje.

komentarz 25 stycznia 2016 przez Łukasz Wasilewski Mądrala (5,190 p.)
Możesz w skrócie powiedzieć dlaczego? Staram się jak najwięcej używać wskaźników, nie tworzyć obiektów "normalnie" tylko rezerwować na nie pamięć. Zamiast "." używa się jedynie "->". Wg. Symfonii C++ dostęp do wskaźnika X jest szybszy od dostępu do elementu X dlatego zwykle tam gdzie mogę, rezerwuje pamięć i tworzę wskaźnik, bądź rezerwuje sobie tablice wskaźników. To źle?

Przepraszam za tyle pytań ale jestem jeszcze na etapie łapania nawyków więc wolałbym je sobie prawidłowo wyrobić. :)
komentarz 25 stycznia 2016 przez Dash Nałogowiec (29,650 p.)
  1.  Czytelność kodu: Wskaźnik na wskaźnik,  czy innego tego typu stworki działają w małych programach, przy czymkolwiek większym już sam autor zacznie się zastanawiać "a to to to co wskazuje?". Analiza takiego kodu jest bardzo nieprzyjemna. Operowanie czy trzymanie jedynie wskaźników jest bardzo dobre, ale musi być czyste i przejrzyste. W przykładowym kodzie deklarujesz w klasie wskaźniki zamiast gotowych danych, co jest imo niepotrzebne. I tak w konstruktorze musisz je "zapełnić". 
  2. Żeby funkcja nie musiała kopiować zmiennej do swojego wnętrza możesz użyć przekazania parametru przez referencję zamiast wskaźnika. Mała rzecz a cieszy i pozwala uniknać tworzenia kolejnych wskaźników. 
  3. Najważniejsze!!! Jeżeli odwołujemy się do wskaźnika który już nie posiada wartości dzieję się coś bardzo niefajnego. Szczególnie ża taki błąd stosunkowo ciężko wyelminować z logiki programu. Gwarantuje, że nawet w pisanym przez siebie kodzie, który znasz na wylot, prędzej czy później pogubisz się we wskaźnikach i tym co przechowują, jeżeli będziesz ich nadużywał. To doprowadzi do błędów i wycieków pamięci. Zdecydowanie lepszym rozwiązaniem są inteligentne wskaźniki (unique_ptr i shared_ptr) oraz dynamiczne kontenery STL. Używanie surowych wskaźników w nowoczesnych programach powinno być ograniczone do minimum. 

To takie trzy podstawowe rzeczy. Dochodzi jeszcze alkoacja stos/sterta czy zasady OOB takie jak enkapsulacja danych czy możliwie mała ilość powiązań między klasami. Wskaźniki w tym zdecydowanie nie pomagają. Nie mówię broń Boże że są złe, są genialnym rozwiązaniem, trzeba być zwyczajnie ostrożnym,

+1 głos
odpowiedź 25 stycznia 2016 przez criss Mędrzec (172,590 p.)
Nie musisz się tym wszystkim martwić. Za to odpowiada system operacyjny. Jak jest wyszukiwane miejsce na alokacje tablicy (tak dobrać komórke pierwszego elemntu żeby starczyło ciągłego miejsca na całą tablice) - nie mam pojęcia, ale też się kiedyś zastanawiałem. W każdym razie - jeśli twój program próbowałby uzyskać dostęp do pamięci przydzielonej innemu programowi, od razu dostanie crasha. Debugger pokaże wtedy segmentation fault.

Podobne pytania

+1 głos
1 odpowiedź 2,117 wizyt
+1 głos
1 odpowiedź 1,664 wizyt
pytanie zadane 24 lutego 2018 w C i C++ przez Sic Dyskutant (8,510 p.)
0 głosów
1 odpowiedź 1,437 wizyt

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...