Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dlaczego ustawianie wartości elementom poza zakresem iteratorów wektora "działa".

Ostatnio zmodyfikowano 2017-05-27 20:05
Autor Wiadomość
RazzorFlame
Temat założony przez niniejszego użytkownika
Dlaczego ustawianie wartości elementom poza zakresem iteratorów wektora "działa".
» 2017-05-27 17:38:45
Dziwne strasznie zachowanie ideone.com:
C/C++
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector < int > abc;
    abc = { 5, 10, 15, 20 };
    abc.resize( 4 );
    std::cout << *( abc.end() + 100 ) << std::endl;
    *( abc.end() + 100 ) = 10;
    std::cout << abc.back() << std::endl;
    std::cout << *( abc.end() + 100 ) << std::endl;
    std::cout << "Capacity: " << abc.capacity() << std::endl;
    std::cout << "Size: " << abc.size() << std::endl;
    return 0;
}
Pokazuje:

0
20
10
Capacity: 4
Size: 4
http://ideone.com/a0Pock
Wypisałem sobie capacity i size, żeby sprawdzić czy przypadkiem vector nie ma takiego zabezpieczenia przed niepoprawnymi iteratorami, ale nie.
Dla pewności czy przypadkiem vector sobie nie zarezerwował większej ilości pamięci użyłem vec.resize(4) ale wciąż to samo. Dziwne.
Czy to zwykły fuks, że nadpisuję pamięć randomowych adresów i nie dostaję wyjątku czy jakiś specjalny mechanizm czy co innego?
Ktoś mi to wytłumaczy?
P-161668
karambaHZP
» 2017-05-27 18:11:29
Użycie miejsca poza vectorem jest UB. Dziś zadziałało, a jutro nie zadziała.
std::vector nie sprawdza, czy użytkownik pisze poza pamięcią (poza metodą at()).
System czuwa, czy próbujesz pisać po pamięci należącej do innego procesu.
P-161672
pekfos
» 2017-05-27 19:02:57
System przydziela pamięć procesowi w całych stronach pamięci, które zwykle mają rozmiar 4k.
C/C++
#include <iostream>
#include <cstdint>

int main()
{
    char * p = new char;
    std::cout <<( void * ) p << std::endl;
   
    char * p2 =( char * )( intptr_t( p ) & ~intptr_t( 0xFFF ) );
    std::cout <<( void * ) p2 << std::endl;
   
    for( char * t = p; t < p2 + 4096; ++t )
         * t = 123, std::cout << '.';
   
    std::cout << "LEL\n";
    delete p;
}
Ten program alokuje 1 bajt i nadpisuje wszystkie bajty od zwróconego przez new adresu, do końca strony.
0x1f6b10
0x1f6000
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...........................................LEL
Nadpisz jeden bajt więcej, a program się sypnie. Zacznij 1 bajt wcześniej, a sypnie się na dealokacji. Oczywiście ten program to jedno wielkie UB ;)
Program się raczej nie wysypie przy nadpisywaniu pamięci, ale nie ma żadnych gwarancji, że niczego nie naruszy. Dalej się może wysypać na dealokacji, lub przy wyjściu z programu.

Wypisałem sobie capacity i size, żeby sprawdzić czy przypadkiem vector nie ma takiego zabezpieczenia przed niepoprawnymi iteratorami, ale nie.
Tzn czy przypadkiem nie zaalokował więcej pamięci, na wypadek błędnego użycia? Litości..
P-161674
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2017-05-27 20:05:12
Dzieki, warto wiedzieć.
P-161679
« 1 »
  Strona 1 z 1