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

question-closed Segmentation fault, std::vector

Object Storage Arubacloud
+1 głos
732 wizyt
pytanie zadane 19 maja 2016 w C i C++ przez draghan VIP (106,230 p.)
zamknięte 19 maja 2016 przez draghan

Witam.

Jakieś pomysły, dlaczego wywala mi segfault w momencie wywołania std::vector::clear()? Jest to vector prostych obiektów, bez żadnych wskaźników czy innych tego typu historii. Debugger wskazuje na plik stl_vector.h, na funkcję:

      /**
       *  Erases all the elements.  Note that this function only erases the
       *  elements, and that if the elements themselves are pointers, the
       *  pointed-to memory is not touched in any way.  Managing the pointer is
       *  the user's responsibility.
       */
      void
      clear() _GLIBCXX_NOEXCEPT
      { _M_erase_at_end(this->_M_impl._M_start); }

Sam vector to std::vector <Segment> body;, gdzie Segment jest zdefiniowany jako:

enum class Direction
{
    up,
    down,
    right,
    left,
};

class Segment
{
public:
    Segment();
    Segment(int x, int y, Direction dir, int block_size);

    bool intersect(const Segment &s) const;

    int get_x() const;
    int get_y() const;
    int get_size() const;
    Direction get_direction() const;

    void move_forward();
    void move_backward();
    void change_position(int x, int y);
    void set_position(int x, int y);
    void change_direction(Direction direction);

private:
    uint8_t pos_x, pos_y, size;
    Direction dir;
};
komentarz zamknięcia: Problem rozwiązany przez przeinstalowanie GCC.
1
komentarz 19 maja 2016 przez adrian17 Ekspert (345,160 p.)
Musiałbyś pokazać znacznie większy kontekst albo cały kod. A co mówi debugger?
komentarz 19 maja 2016 przez draghan VIP (106,230 p.)

Wyciąłem kod z pierwotnej aplikacji i wrzuciłem w pusty projekt. Main wygląda tak:

#include "segment.hpp"
#include <vector>

int main()
{
    std::vector <Segment> body;
    Segment s(1, 1, Direction::right, 2);
    // dodaję kilka przesuniętych względem siebie segmentów:
    body.push_back(s);
    s.move_forward();
    body.push_back(s);
    s.move_forward();
    body.push_back(s);
    body.clear(); // ??
}

Deklaracja Segment wyżej. Definicje metod:

#include "segment.hpp"

bool Segment::intersect(const Segment& s) const
{
    if((this->pos_x < s.pos_x + s.size) &&
       (this->pos_x + this->size > s.pos_x) &&
       (this->pos_y < s.pos_y + size) &&
       (this->pos_y + this->size > s.pos_y))
       return true;
    else return false;
}

int Segment::get_x() const
{
    return pos_x;
}

int Segment::get_y() const
{
    return pos_y;
}

int Segment::get_size() const
{
    return size;
}


Direction Segment::get_direction() const
{
    return dir;
}

void Segment::change_position(int x, int y)
{
    pos_x += x;
    pos_y += y;
}

void Segment::set_position(int x, int y)
{
    pos_x = x;
    pos_y = y;
}

void Segment::move_forward()
{
    uint8_t dx = 0, dy = 0;
    switch(dir)
    {
    case Direction::down:
        dy = size + 1;
        break;
    case Direction::left:
        dx = -size - 1;
        break;
    case Direction::right:
        dx = size + 1;
        break;
    case Direction::up:
        dy = -size - 1;
        break;
    }
    change_position(dx, dy);
}

void Segment::move_backward()
{
    uint8_t dx = 0, dy = 0;
    switch(dir)
    {
    case Direction::down:
        dy = -size-1;
        break;
    case Direction::left:
        dx = size+1;
        break;
    case Direction::right:
        dx = -size-1;
        break;
    case Direction::up:
        dy = size+1;
        break;
    }
    change_position(dx, dy);
}

Segment::Segment(int x, int y, Direction direction, int block_size)
:pos_x(x), pos_y(y), size(block_size), dir(direction)
{
}

Segment::Segment()
:pos_x(0), pos_y(0), size(2), dir(Direction::right)
{
}


void Segment::change_direction(Direction direction)
{
    dir = direction;
}

...nic szczególnego. Same proste porównania i dodawanie.

Dochodząc do body.clear() dostaję segmentation fault.

Debugger pisze:

Program received signal SIGSEGV, Segmentation fault.
At /usr/include/c++/6/bits/stl_vector.h:1210

W call stacku mam tylko main i vector::clear, więc nic mi to nie mówi. Wszystkie pola mają wartości w porządku.

Pierwszy raz się z czymś takim spotykam. Powinno śmigać i hulać, aż miło. Jestem naprawdę skonsternowany.

1
komentarz 19 maja 2016 przez maly Nałogowiec (37,190 p.)
No to masz wesoło :)

Wygląda jakby clear wywoływane było na usuniętym wektorze.

Może masz załączone jakieś optymalizacje?

Jaki masz kompilator?
komentarz 19 maja 2016 przez adrian17 Ekspert (345,160 p.)
Wygląda podejrzanie. Jesteś w stanie zreprodukować to mniejszym kodem (np. w jednym pliku)? Mógłbyś podać flagi użyte do kompilacji?
komentarz 19 maja 2016 przez draghan VIP (106,230 p.)
To było GCC 6.1.1., jedyna opcja to ta od C++11. Przeinstalowałem GCC-6. Problem zniknął, niesmak pozostał.
komentarz 19 maja 2016 przez adrian17 Ekspert (345,160 p.)
...oh, nie zauważyłem że to Ty jesteś autorem pytania. Jest jakaś szansa że trafiłeś na bug w GCC, bo bugi przy rozpakowywaniu paczek raczej nie są częste.

...tak, ufam apt'owi (czy cokolwiek używasz) bardziej niż GCC.
komentarz 19 maja 2016 przez draghan VIP (106,230 p.)
Cały czas pracowałem z GCC 4.9, ostatnio się rozejrzałem i zobaczyłem że w repo jest już wersja 6, to sobie zainstalowałem. Od tamtego czasu bawiłem się raczej GCC-ARM. Ale jak skompilowałem ten sam projekt jako build dla SFML, to nagle przestał mi działać. Po sporej dawce wyrwanych włosów napisałem tutaj.
Naprawdę nie wiem, co to się porobiło. Wersja GCC się przez ten czas nie zmieniła, nadal jest to 6.1.1. W ustawieniach repozytoriów nie grzebałem. Błąd był, a nie ma. Nie wiem, co o tym myśleć.

W weekend może przejrzę logi, czy coś. Tylko nie wiem, jakie. Jakieś pomysły?
komentarz 19 maja 2016 przez adrian17 Ekspert (345,160 p.)
4.9->5.0 była zmiana ABI, taki Debian miał z tym duże problemy przez jakiś czas, dużo paczek musieli przebudować. Trudno mi powiedzieć co mogło się u Ciebie dziać. Tym bardziej, że już nie reprodukujesz.

1 odpowiedź

–3 głosów
odpowiedź 19 maja 2016 przez niezalogowany
Z tego co wiem to jak masz vector nazwijmy go vec to powinno byc vec.clear()
komentarz 19 maja 2016 przez draghan VIP (106,230 p.)

Podałem nazwę metody, przy której program mi crashuje, nie konkretną linię z kodu. Jeśli Ci zależy, to podam i to:

std::vector <Segment> body;
/* operacje na body, głównie push_back() i 
wywołanie metod akcesorów i Segment::move_forward() [zmienianie współrzędnych]
*/
body.clear(); // tutaj następuje crash

 

komentarz 19 maja 2016 przez Fenix Nałogowiec (26,750 p.)
A body nie powinno być przypadkiem wskaźnikiem?
komentarz 19 maja 2016 przez draghan VIP (106,230 p.)
Obiekt body nie powinien być wskaźnikiem.

Podobne pytania

0 głosów
1 odpowiedź 158 wizyt
pytanie zadane 5 sierpnia 2016 w C i C++ przez Pac Plus Mądrala (5,560 p.)
0 głosów
1 odpowiedź 194 wizyt
pytanie zadane 19 grudnia 2015 w C i C++ przez emSon Stary wyjadacz (10,480 p.)
0 głosów
1 odpowiedź 217 wizyt
pytanie zadane 15 sierpnia 2016 w C i C++ przez ignacjusz Bywalec (2,390 p.)

92,605 zapytań

141,451 odpowiedzi

319,743 komentarzy

61,985 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!

...