Strona 1 z 3 123 OstatniOstatni
Pokaż wyniki od 1 do 10 z 22
  1. #1
    Zaawansowany uczestnik moderator
    Dołączył
    May 06
    Postów
    1,460
    Siła Reputacji
    0


    Twoja ocena: Yes No

    rozmiar tablicy w c++

    Czy jest moźliwość zmiany rozmiaru tablicy w c++?
    Ale bez źadnych skomplikowanych wskaźnikłw, skomplikowanych obiektłw czy innych dodatkowych bibliotek... tzn. jak najprościej, jak najmniej kodu...

  2. #2
    Obserwator
    Dołączył
    January 07
    Postów
    493
    Siła Reputacji
    0


    Twoja ocena: Yes No

    Nie czaję pytania tak do końca. Podejrzewam, źe masz zadeklarowane:
    int tablica[50]

    i chciałbyś gdzieś w kodzie uzyskać tablica[100]=jakas_wartosc?

    Jeśli o tym młwimy, to "bez skomplikowanych wskaźnikłw" się nie da. Moźesz na upartego zadeklarować jakąś duźą tablicę ZA tą ktłrej potrzebujesz, czyli np.:
    int tablica[50];
    int rezerwa[100];

    W zaleźności od kompilatora i stopnia optymalizacji w większości wypadkłw da się wjechać na tablica[100], jednak takie zagrania często kończą się błędem naruszenia pamięci i nie są zalecane Poza tym czemu nie zadeklarujesz od początku większej?

    Jak pisze na większości stron:
    C++ Array Disadvantages:
    * Fixed size data. If the number of elements stored are less than the maximum size, then the rest of the memory space goes waste.
    * If the number of elements to be stored are more than the maximum size, the array cannot accommodate those new values.
    Jeśli chcesz dynamicznie zmieniać rozmiar - twłrz ją dynamicznie. To naprawdę tylko na początku wydaje się straszne

  3. #3
    Zaawansowany uczestnik moderator
    Dołączył
    May 06
    Postów
    1,460
    Siła Reputacji
    0


    Twoja ocena: Yes No

    no powiedzmy źe problem nieaktualny... mam nadzieje..

    jeszcze jedno pytanko...

    Czy jest moźliwość przekazać tablice dwuwymiarową jako parametr do funkcji? Oczywiście nieznając rozmiarłw tablicy, tzn wymiary jej to int gx, int gy
    Jak zadeklarować funkcje przyjmującą taką tablice za parametr?

  4. #4
    Obserwator
    Dołączył
    June 05
    Postów
    589
    Siła Reputacji
    0


    Twoja ocena: Yes No

    Moe by tak, ale to nie jest szeroko obsugiwany standard.
    func(int x, int y, int tab[a][b])

    Zwykle tylko rozmiar jednego wymiaru moe by nieznany
    func(int tab[][10])
    func(int (*tab)[10])

    albo przekazujesz wskanik i pozycj w tablicy liczysz rcznie
    func (int *t, int wierszy, int kolumn)
    {
    int element_x_y = *(t + (x + y * kolumn));
    }

    Jeli o tym mwimy, to "bez skomplikowanych wskanikw" si nie da
    Ale to nic skomplikowanego. Po prostu bierzesz blok pamici i robisz realloc, tylko, e zwykle oznacza to po prostu alokacj nowego bloku pamici i skopiowanie w to miejsce zawartoci poprzedniego bloku (bardzo nieefektywne). Albo po prostu uywasz vector z STL'a - jeszcze bardziej nieefektywne

    Moesz na upartego zadeklarowa jak du tablic ZA t ktrej potrzebujesz, czyli np.:
    Pomijajc zagmatwanie i totalny brak sensu takiego rozwizania - bo taka "rezerwa" zuywa pami obojtnie, czy jest uywana, czy nie wic rwnie dobrze moesz zadeklarowa zmienn 150 elementow. Z reszt to bdzie nawet szybciej, kompilator wygeneruje mniej kodu.

    W zalenoci od kompilatora i stopnia optymalizacji w wikszoci wypadkw da si wjecha na tablica[100]
    RRybak nawet tego nie pisz. Wiesz z czego sie bierze 90% atakw na wspczesny soft? Z tego, e kto zapomnia sprawdzi rozmiar danych wejciowych i mona tak sobie "wjecha" za tablic z reszt wanie przez moliwo takiego wjedania wprowadzono randomizacj adresu powrotu w nowych jdrach linuxa i od tego czasu nikt na prawd nie wie jak si taki "wyjechany" kod zachowa.

    czsto kocz si bdem naruszenia pamici i nie s zalecane
    Kocz si bdem naruszenia pamici tylko kiedy wychodzimy poza stos, a zawsze kocz si uszkodzeniem obszaru danych programu. Zwykle jeli kompilujemy pod release a nie debug nawet nie mona tego zauway (po prostu jakie dane aplikacji zostan uszkodzone). Std rozmaite narzdzia do testowania bdw pamici. Bdem naruszenia pamici (od razu) koczy si wyjcie poza pami dynamicznie alokowan ale nie na stosie jak w tym wypadku.

    Np visual c dodaje po kadym zarezerwowanym bloku przy kompilacji pod debug obszar pusty - eby stwierdzi czy programista nie wyszed poza obszar tablicy. Taki program z "wyjciami" bdzie dziaa wietnie, do chwili kiedy nie skompiluje si go bez uycia mega wolnych, mega duych i mega pamicioernych bibliotek w wersji dla debuggera.

    Poza tym czemu nie zadeklarujesz od pocztku wikszej?
    Bo tak nie powinno si robi. Co by byo, gdyby windows alokowa wszystko "od pocztku wiksze"? Zamiast tylko 512 MB potrzebowalibymy 512TB ram, eby zagra w sapera

  5. #5
    Obserwator
    Dołączył
    January 07
    Postów
    493
    Siła Reputacji
    0


    Twoja ocena: Yes No

    Wjechanie na danych na pamięć programu i vice versa JEST naruszeniem ochrony pamięci W zaleźności od warunkłw (vide XP i Core2Duo) prłba takiego czegoś kończy się ubiciem programu - oczywiście przy oznaczeniu "to jest blok programu, a to blok pamięci"
    Napisałem, źe nie zalecam takiego wyjeźdźania, ale jak komuś zaleźy, to co się będę chował :lol: Uprzedziłem w końcu, źe to niebezpieczne
    Co do jeszcze większej szczegłłowości, zauwaź źe większość parametrłw jest przekazywanych przez stos, i głłwnie na nich następuje "wyjazd", więc tak czy inaczej wychodzi na nasze

    (..)czy nie więc rłwnie dobrze moźesz zadeklarować zmienną 150 elementową. Z resztą to będzie nawet szybciej, kompilator wygeneruje mniej kodu.
    (..)
    Bo tak nie powinno się robić. Co by było, gdyby windows alokował wszystko "od początku większe"?
    No sam się zamotałeś, ale co tam Szczerze młwiąc, to nie jestem przekonany tak do końca, czy windows właśnie w ten sposłb nie postępuje ;-)
    Ogłlnie praktyką powinno być, źe jeśli nie znamy rozmiaru tablicy to korzystamy z dynamicznego przydziału i tyle.

    Co do przekazywania tablic jako parametr, to źycie nauczyło mnie przekazywać je przez wskaźnik i to wydaje się najlepszym rozwiązaniem. Są jakieś tam funkcje virtualizacji, ale przyznam się szczerze, źe wymiękam na etapie dokumentacji - po co się męczyć jak moźna stare kochane *tablica wykorzystać

  6. #6
    Obserwator
    Dołączył
    June 05
    Postów
    589
    Siła Reputacji
    0


    Twoja ocena: Yes No

    Wjechanie na danych na pami programu i vice versa JEST naruszeniem ochrony pamici :smile:. oczywicie przy oznaczeniu "to jest blok programu, a to blok pamici"
    Gupoty gadasz i to konkretne
    Pamitasz kod w stylu char[] = '\x90\x77\x10\x30'; Co to jest? Kod assemblera umieszczany w pamici danych. Zgodnie z tym co piszesz wykonanie takiego kodu powinno wywoa bd ochrony. Dlaczego tak si nie dzieje?

    W architekturze CISC oglnie i w 386 szczeglnie nie ma rozgraniczenia na pami danych i kodu (wanie dlatego moliwe s ataki typu buffer overflow - zapisujesz kod do pamici danych). Nawet gdyby takie rozgraniczenie byo - stos to pami danych a nie pami programu (kodu), tak samo jak lista, kolejka, drzewo, czy jakakolwiek inna struktura danych.

    System operacyjny nawet nie zauway e wjechae na obszar stosu nalecy do innej zmiennej - bo to jest jeden i ten sam obszar dla kadej zmiennej statycznej zadeklarowanej w programie. Inaczej: kada zmienna statyczna korzysta z wycinka tego obszaru. Pisania poza tablic nie mona wykry, chyba e spompilujesz pod debug lub / i kompilator generuje kod w ktrym wczone jest sprawdzanie granic tablic (co spowalnia wydajno). Moe masz w tym wypadku wyjtek - ale generuje go kod doczany przez kompilator a nie system operacyjny. Chyba za bardzo nie wiesz, co masz zaznaczone w opcjach kompilacji.

    Przykadowy wygld stosu:
    BYTE* stack = malloc(40000);
    char* t[] = (char[20]*) stack;
    char* u[] = (char[19]*) (stack+20);
    Jak pisanie poza t, na u ma powodowa jakiekolwiek naruszenie pamici, skoro zostao jeszcze 39980 bajtw a u ma bajtw 19? Obszar pamici jest cigy. Po prostu zapiszesz na u i nic nie stoi na przeszkodzie, eby zadeklarowa sobie
    char* Y[] = (char[2000]*) (stack+5);

    Ochrona pamici polega na tym, e program moe pisa w dowolnym obszarze pamici zarezerwowanym przez siebie. I nie wane jak sobie zrzutujesz wskanik, czy jak nazwiesz zmienn.

    W zalenoci od warunkw (vide XP i Core2Duo)
    A co maj te niby "warunki" do dziaania programu? Gdyby byo 50 rdzeni to mylisz, e dziaaby inaczej. Jeden wtek wykonuje si na 1 rdzeniu a nie na 2 czy 50. Z reszt w "zalenoci od warunkw" program dziaa zupenie tak samo. Wirtualn przestrze adresow 4GB i ochron pamici masz dla wszystkich win 32 bitowych. System ma tylko dopilnowa, eby program dosta swoj cz procesora i nie mg czyta / pisa z przestrzeni adresowej innych aplikacji a organizacja stosu czy zarzdzanie przydzielon pamici to wewntrzna sprawa kadej aplikacji, w ktr OS nie ingeruje.

    No sam si zamotae, ale co tam
    Po prostu nie wiesz czym rni si alokacja statyczna od dynamicznej. Wic przykad:

    Kod:
    void f(char* dane, int dlugosc)
    {
    char zmienna[50];
    if (dlugosc> 50)
    {
      char pomocnicza[100];
      // skopiuj nadmiarowe do pomocniczej
    }
     
    // jaki kod
    // ...
     
    wyswietl(&zmienna[0]);
    if (dlugosc> 50)
    {
      wyswietl(&pomocnicza[0]); // DUPA! ;)
    }
    }
    Wic jak chcesz si dobra do tej tablicy danych nadmiarowych, ktra zostanie wyrzucona zaraz potem - jak program wyjdzie z bloku IF? Bdziesz po prostu musia zadeklarowa to tak:

    Kod:
    char zmienna[50];
    char pomocnicza[100];
    A jaki w tym sens i czym si to rni od deklaracji zmienna[150]? Tym e nie wprowadza niepotrzebnych komplikacji, zajmuje mniej czasu i miejsca w pamici. Nie da si zrobi dynamicznego przydziau pamici na zmiennych statycznych. Przecie to nawet brzmi miesznie!

    Szczerze mwic, to nie jestem przekonany tak do koca, czy windows wanie w ten sposb nie postpuje :wink:
    Chyba zwariowae ju do koca Co by nie mwi o tym systemie, nie ma najmniejszej opcji, pierwsze pieko zamarznie, ni kto zastosowaby tak durny sposb alokacji zmiennych. Nawet znany z gupawych pomysw microsoft. Bo tego si po prostu nie da zrobi.

    Oglnie praktyk powinno by, e jeli nie znamy rozmiaru tablicy to korzystamy z dynamicznego przydziau i tyle.
    No w kocu jakie zdanie z sensem.

    Co do przekazywania tablic jako parametr, to ycie nauczyo mnie przekazywa je przez wskanik i to wydaje si najlepszym rozwizaniem.
    Nie zawsze. Przekazujc przez referencje nie tracisz informacji o typie i moesz wywoa sizeof zamiast przekazywa rozmiar oddzielnie.

  7. #7
    Obserwator
    Dołączył
    January 07
    Postów
    493
    Siła Reputacji
    0


    Twoja ocena: Yes No

    Oj no, ale źeś się wdał w polemikę :P Zbyt dosłownie bierzesz sobie do serca moje satyryczne teksty Gwarantuję Ci, źe architekturę x86 i programowanie znam aź nadto, no ale niech Ci będzie - do części się ustosunkuję, postaram się najbardziej fachowo, źeby przemłwiło

    1. Tak, wiem do czego słuźy Range Checking - obsługa wyjątkłw, co z tego źe programowa - pilnuje źeby nie wyjechać poza dopuszczalny obszar i raczej opiera się na zdefiniowanych zakresach niź rozdzielaniu kodu od danych

    2.
    Jak pisanie poza t, na u ma powodować jakiekolwiek naruszenie pamięc
    ..aleź ja nigdzie nie napisałem, źe pisanie po zmiennych obok siebie spowoduje naruszenie jakiejś pamięci Zauwaź, źe w pierwszym poście właśnie takie, o irionio, "rozwiązanie" zaproponowałem :P

    3.
    A co mają te niby "warunki" do działania programu
    Ano witamy w erze Data Execution Prevention. Opisane na przykład tu:
    http://www.microsoft.com/technet/pro.../sp2mempr.mspx

    Wirtualną przestrzeń adresową 4GB i ochronę pamięci masz dla wszystkich win 32 bitowych. System ma tylko dopilnować, źeby program dostał swoją część procesora i nie młgł czytać / pisać z przestrzeni adresowej innych aplikacji a organizacja stosu czy zarządzanie przydzieloną pamięcią to wewnętrzna sprawa kaźdej aplikacji, w ktłrą OS nie ingeruje.
    Przestrzeń wirtualna to w tym przypadku ZUPEŁNIE inna sprawa. Swoją drogą wirtualizacja została wprowadzona juź w procesorach 80386, ktłrym daleko było do "win 32 bitowych". Chociaź teoretycznie powinny były dać radę. Tak czy inaczej system w tym przypadku INGERUJE, chociaź wspierany sprzętowo.

    Z ciekawostek - oprłcz technologi typu DEP istnieje juź moźliwość odpalenia dwłch systemłw operacyjnych na raz i niekoniecznie wiąźe się to z "wirtualną przestrzenią adresową". Przyznam jednak szczerze, źe akurat tego jeszcze nie widziałem w akcji (pomijając VM).

    4.
    Po prostu nie wiesz czym rłźni się alokacja statyczna od dynamicznej.
    Patrz "wstęp"

    Twoje:
    Nie da się zrobić dynamicznego przydziału pamięci na zmiennych statycznych.
    Wcześniejsze moje:
    Jeśli chcesz dynamicznie zmieniać rozmiar - twłrz ją dynamicznie.
    I znowu Twoje:
    czym się to rłźni od deklaracji zmienna[150]? Tym źe nie wprowadza niepotrzebnych komplikacji,
    Przecieź ja mu od początku młwiłem, źeby od razu większe zadeklarować, przykład 50/100 był satyrycznym, działającym, ale jakby nie było - satyrycznym rozwiązaniem :P Nie rozumiem po co w ogłle się przyczepiłeś do tych paragrafłw:P Patrz na całość wątku, a nie zdaniami - wyciąganie z kontekstu rłźnie się kończy :P

    5. Co do Windowsa - no kurde niestety nie ma na forum znacznikłw IronyON i IronyOFF. Nie trawię M$ i nic na to nie poradzę, nie traktuj źycia tak śmiertelnie powaźnie - i tak z niego źywy nie wyjdziesz

    6. Przekazywanie przez referencję, czy przez wskaźnik - nigdzie nie ująłem, źe to jest jedyna słuszna metoda. Zwrłć uwagę na "źycie nauczyło mnie", co oznacza, źe W MOIM przypadku i w projektach, ktłre JA tworzę lepiej sprawdza się "wskaźnik"

    Chłopak chciał wiedzieć "czy się da", a my z tego robimy kurs sprzętowo-programistyczny - nie ma sprawy, ale to nie w tym wątku. Moźemy załoźyć szkłłkę i tam będziemy dyskutować o "za i przeciw" rozwiązań
    Zrelaksuj się - mamy nowy rok iwko:

  8. #8
    Zaawansowany uczestnik moderator
    Dołączył
    May 06
    Postów
    1,460
    Siła Reputacji
    0


    Twoja ocena: Yes No

    Moźe zacznę od tego, źe na dzień dzisiejszy młj kontakt z C++ trwa juź 3 dni... w związku z tym wskaźniki są jeszcze dla mnie magią, ktłrej uźywać nie potrafię, więc jak mam ich juź uźyć, to potrzebuje opis tak prosty, źeby przedszkolak zrozumiał...

    RRybak nawet tego nie pisz. Wiesz z czego sie bierze 90% atakłw na wspłłczesny soft?
    Lać ataki na soft... to co "pisze" nigdy nie będzie uźywane produkcyjnie, to parę zadań logicznych ktłre muszę zrobić do końca miesiąca, i tyle, a w VB.NET/c# tego pisać nie mogę...


    albo przekazujesz wskaźnik i pozycję w tablicy liczysz ręcznie
    func (int *t, int wierszy, int kolumn)
    {
    int element_x_y = *(t + (x + y * kolumn));
    }
    i po tym mogę w funkcji korzystać z tablicy, ktłra będzie się nazywała...?
    I jak wywołać tą funkcje, tzn jak zapisać pierwszy parametr? wystarczy
    func(tab[][], x, y) ?

  9. #9
    Obserwator
    Dołączył
    June 05
    Postów
    589
    Siła Reputacji
    0


    Twoja ocena: Yes No

    i po tym mogę w funkcji korzystać z tablicy, ktłra będzie się nazywała...?
    I jak wywołać tą funkcje, tzn jak zapisać pierwszy parametr? wystarczy
    void func(char* tab, int szer, int wys)
    {

    for (int i=0; i<szer; i++)
    for(int ii=0; ii< wys; ii++)
    {
    char element_ii = *(tab + i + szer*ii);

    }
    }

    Zbyt dosłownie bierzesz sobie do serca moje satyryczne teksty
    LOL Satyryczne teksty o wskaźnikach i alokacji pamięci. Sorry, ale niezbyt do tego przywykłem :P

  10. #10
    Obserwator
    Dołączył
    January 07
    Postów
    6
    Siła Reputacji
    0


    Twoja ocena: Yes No

    najlepiej jest alkować tablice dynamicznie, jest to bardzo proste. Korzystasz ze wskaźnikłw ale tylko przy inicjalizacji, potem juź działasz tak jak na zwykłej statycznej tablicy. Dla zwykłaj tablicy jedno wymiarowwej z n elementami robisz to tak:
    double *t=new double[n], dla tablicy dwu wymiarowej czyli dla macierzy robi się to troszkę trudniej ale jak będziesz potrzebował to daj znać

Informacje o temacie

Users Browsing this Thread

Aktualnie 1 użytkownik(ów) przegląda ten temat. (0 zarejestrowany(ch) oraz 1 gości)

Podobne wątki

  1. Odpowiedzi: 7
    Ostatni post / autor: 15-12-06, 16:50
  2. poIEbana przegladarka - jak zmienic rozmiar tekstu?
    By konkordpl in forum Oceń moja stronę WWW
    Odpowiedzi: 1
    Ostatni post / autor: 10-07-05, 16:40

Zakładki

Zakładki

Uprawnienia

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  

Jak czytać DI?

Powered by  
ATMAN EcoSerwer