Kyriet Temat założony przez niniejszego użytkownika |
Dziwne zachowanie dynamicznych tablic czy brak mi wiedzy na ich temat? » 2015-03-09 18:35:04 Myślałem, że całkiem dobrze rozumiem "podstawy" wskaźników, a teraz się okazało, że nie ogarniam. char * tab_char = new char[ 3 ] Do tej pory myślałem, że jest to dynamiczne alokowanie pamięci (tablicy), w tym wypadku 3-elementowej. Jeśli na prawdę jest to tablica 3-elementowa, to jak wytłumaczyć: tab_char[ 999 ] = 'Z'; cout << tab_char[ 999 ]; Że coś takiego działa? Przecież nie powinien istnieć element o indeksie 999, a ja właśnie wpisuję tam literkę 'Z'. Niżej w programie pokazuję też dynamiczną tablicę int . Wtedy dzieją się cuda: W czystym programie, to działa: int * tab_int = new int[ 3 ]; tab_int[ 8 ] = 21; cout << tab_int[ 8 ]; A w programie poniższym: tab_int[ 8 ] = 22; Powoduje error po zakończeniu aplikacji. Sprawdzałem, bo po skasowaniu tej linijki oraz cout << tab_int[ 8 ] << " "; Visual nie krzyczał nic po zakończeniu. #include <iostream> #include <conio.h>
using namespace std;
int main() { char * tab_char = new char[ 3 ]; tab_char[ 0 ] = 'A'; tab_char[ 1 ] = 'B'; tab_char[ 2 ] = 'C'; cout << tab_char[ 0 ] << " "; cout << tab_char[ 1 ] << " "; cout << tab_char[ 2 ] << " "; tab_char[ 4 ] = 'X'; tab_char[ 10 ] = 'Y'; tab_char[ 999 ] = 'Z'; cout << tab_char[ 4 ] << " "; cout << tab_char[ 10 ] << " "; cout << tab_char[ 999 ] << endl; int * tab_int = new int[ 3 ]; tab_int[ 0 ] = 1; tab_int[ 1 ] = 2; tab_int[ 2 ] = 3; cout << tab_int[ 0 ] << " "; cout << tab_int[ 1 ] << " "; cout << tab_int[ 2 ] << " "; tab_int[ 3 ] = 20; tab_int[ 7 ] = 21; tab_int[ 8 ] = 22; cout << tab_int[ 3 ] << " "; cout << tab_int[ 7 ] << " "; cout << tab_int[ 8 ] << " "; _getch(); return 0; }
Drukuje: A B C X Y Z 1 2 3 20 21 22
I na koniec ERROR Jeżeli odnoszenie się do elementu 8 lub więcej, to powoduje to błąd w powyższym programie: tab_int[ 8 ] = 22; To dlaczego tutaj nie ma ERROR'a? #include <iostream> #include <conio.h>
using namespace std;
int main() { int * tab_int = new int[ 3 ]; tab_int[ 8 ] = 21; tab_int[ 999 ] = 22; cout << tab_int[ 999 ] << " " << tab_int[ 8 ]; _getch(); return 0; } Dziękuję za pomoc i pozdrawiam. |
|
tristan |
» 2015-03-09 19:10:30 Tablica to tak naprawdę wskaźnik na pierwszy element. A zapis tablica[100] to skok na element 100 od początku zapisanego w tablicy. I języki takie jak C i C++ nie sprawdzają, że wychodzisz poza zakres. Wychodząc poza zakres trafiasz w inne zmienne, co może psuć działanie programu, zmieniać ich zwartość itp. Ale póki nie wyjdziesz poza zakres pamięci przydzielonej dla programu, to se piszesz po pamięci ile chcesz. Na tym polega właśnie atak typu przepełnienie bufora.
https://pl.wikipedia.org/wiki/Przepe%C5%82nienie_bufora |
|
akwes |
» 2015-03-09 19:16:19 W języku C++ nie ma sprawdzenia ważności zakresu tablicy z względów wydajnościowych. Taką funkcję można mieć używając std::vector oraz std::vector::at. W niektórych językach jest to sprawdzane (C#, Java). W C++ tak naprawdę nadpisujesz obszar do którego nie masz prawa (logicznie) i odczytujesz go. W dużej aplikacji mógłbyś właśnie wysadzić koledze jego obiekt w kosmos :) |
|
Kyriet Temat założony przez niniejszego użytkownika |
» 2015-03-09 19:24:39 A dlaczego poniższy program: #include <iostream> #include <conio.h>
using namespace std;
int main() { char * tab = new char[ 3 ]; tab[ 0 ] = 'A'; tab[ 1 ] = 'B'; tab[ 2 ] = 'C'; cout << tab; _getch(); return 0; }
Drukuje: ABCřřřřźźźźźźźź■ţ■ţ■ţ■ţ■
Visual Studio ma możliwość podglądu zawartości zmiennych i tablic w czasie wykonywania programu i przed przypisaniem wartości do tablicy, tablica tab wygląda tak: ÍÍÍýýýý««««««««þîþîþîþîþ Domyślam się, że te 3 pierwsze, inne znaki, to miejsce na moje zmienne, a po przypisaniu zmiennych, tablica wygląda tak: ABCýýýý««««««««þîþîþîþîþ Myślałem, że tablica char działa tak, że jak spróbuję ja wypisać przez cout, to wypisze się cała. No i mam rację, wypisuje się cała, tylko dlaczego przy tworzeniu 3-elementowej tablicy dostaję: ÍÍÍýýýý««««««««þîþîþîþîþ (24 znaki, więc i 24 miejsca na wartości). Wypisuje mi: ABCřřřřźźźźźźźź■ţ■ţ■ţ■ţ■ to również są 24 znaki wliczając ABC. Wyjście poza zakres i wpisanie: tab[ 3 ] = 'D'; będzie zastępować kolejno te dziwne znaczki. Pytanie: dlaczego rezerwując pamięć dla 3 elementów, dostaję tablicę z 24 elementami? |
|
pekfos |
» 2015-03-09 19:26:37 Samo te wyświetlenie, to już wyjście poza tablicę i niezdefiniowane zachowanie. Łańcuch znaków musi się kończyć zerem. |
|
Kyriet Temat założony przez niniejszego użytkownika |
» 2015-03-09 19:35:20 No racja! Całkowicie o tym zapomniałem. Ostatnia komórka ma być NULL . Dziękuję za pomoc. Potrzebowałem wiedzieć jak wyświetlić "na raz" całą tablicę char, bo nie jestem pewien, ale SPOJ jak chce output: ABC To napisanie: cout >> 'A'; cout >> 'B'; cout >> 'C'; Nie zaakceptuje (chyba). Chodzi o to, że nie mogę wypisywać osobno komórek tablicy, tylko na raz całość cout << "ABC"; Tak mi się przynajmniej wydaje. Pozdrawiam i dziękuję za pomoc. |
|
« 1 » |