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

podwójne usunięcie pamięci

Object Storage Arubacloud
0 głosów
544 wizyt
pytanie zadane 26 stycznia w C i C++ przez TOWaD Mądrala (6,000 p.)

Wiem co, ale nie potrafię zrozumieć dlaczego, podmiana wskaźnika wywala program i jak to ominąć, by zwolnić nadmiarowa pamięć.

Otrzymuję komunikat  [w tym programie]

free(): double free detected in tcache 2

Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737348187968) at ./nptl/pthread_kill.c:44
44      ./nptl/pthread_kill.c: No such file or directory.

tak jakby podwójne wywołanie destruktora.

bignum::~bignum() {
    if(ptrlgnr)
        delete[]ptrlgnr;
    // o("usuniento")
}

powodem jest funkcja

void bignum::realloc(char * old,const size_t & newsize) {
    if(!old)
        throw std::bad_alloc();
    char* newone=nullptr;
    newone=new char[newsize+1] {};
    if(newone)
        for(size_t i=0; i<newsize; i++)
            newone[i]=old[i];
    else
        throw std::bad_alloc(); // jeżeli nie udała się rezerwacja pamięci.
    delete [] old;
    old=newone;
    newone=nullptr;
    return;

1 odpowiedź

+1 głos
odpowiedź 26 stycznia przez adrian17 Ekspert (344,860 p.)
wybrane 28 stycznia przez TOWaD
 
Najlepsza
Pierwsze co mi wyskakuje AddressSanitizerem to że wychodzisz poza pamięć, bo iterujesz się po `newsize` elementach, ale `old` może być mniejszy.

A po drugie, no, masz kompletnie źle kopiowanie obiektów. Operator przypisania nic nie robi, a konstruktora kopiującego w ogóle nie ma - więc pewnie kompilator stworzył domyślny, który po prostu kopiuje pola. A stąd już prosta droga do double free, bo można trywialnie i nawet przypadkiem dostać dwa obiekty wskazujące na ten char* i oba wywołają destruktory.

(btw, ten `new bignum` w operator+ też super dziwnie wygląda)
komentarz 14 lutego przez adrian17 Ekspert (344,860 p.)
edycja 14 lutego przez adrian17

nie wiem gdzie dodawać argumenty kompilacji

W konfiguracji projektu masz checkboxy, na przykład: https://learn.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170#ide-msbuild

To zawsze był strzał w stopę. (const <STL contener> & ref), a to, zawsze było ok  (iterator begin, iterator end), ale tu zrobiłem kopię, skoro kopie w c++11 nie są takie złe.

Trudno powiedzieć co tu mówisz i większość brzmi... źle. Szczególnie nie brzmi jakby akurat kopiowanie stringa miało związek z Twoimi problemami, a kopie praktycznie zawsze są niewydajne; C++11 daje tylko więcej narzędzi do ich unikania.

Na godbolt nie działa

Patrząc na screenshota, widzę co najmniej kilka dziwnych rzeczy. -static-libasan, MinGW executor...? Masz dodaną jakąś bibliotekę tam?  Bo ja tylko wkleiłem kod, dodałem -fsanitize=address i tyle: https://godbolt.org/z/nsMM96nra . To jest narzędzie do szybkiego testowania, nie IDE ;D

 

 

 

 

komentarz 14 lutego przez TOWaD Mądrala (6,000 p.)

W konfiguracji projektu masz checkboxy

Zrobione (niestety polski gdzieś przegapiłem opcję w instalacji), ale nic nie dodało na końcu kodu.


Patrząc na screenshota, widzę co najmniej kilka dziwnych rzeczy. -static-libasan

static-libasan  - to chyba było w poradniku nie ważne.

Problem pewnie dotyczy braku cmake (pliku?/katalogu?). Bo nie chciało mi się przyklejać kodu i dodałem plik .zip do kompilatora templates>cmake>project>przeglądaj...

Może jakoś da się, cały projekt dodać.


Trudno powiedzieć ...

STL jednak w większości funkcji używa iteratorów np transform, copy itd, nie referencji

https://en.cppreference.com/w/cpp/algorithm/transform

std::transform
 
C++
Algorithm library
 
Defined in header <algorithm>
		
	(1) 	
template< class InputIt, class OutputIt, class UnaryOperation >

OutputIt transform( InputIt first1, InputIt last1,
                    OutputIt d_first, UnaryOperation unary_op );
...

 

 

komentarz 14 lutego przez adrian17 Ekspert (344,860 p.)

ale nic nie dodało na końcu kodu.

Na oko u mnie działa:

STL jednak w większości funkcji używa iteratorów np transform, copy itd, nie referencji

Bo są uniwersalnym mechanizmem iteracji. To nie znaczy że referencje do rzeczy są "strzałem w stopę", szczególnie w kodzie który ma zero związku z iteracją.

komentarz 14 lutego przez TOWaD Mądrala (6,000 p.)

t

Tak to działa i nawet błąd zgłasza głównym oknie programu.

==9052==ERROR: AddressSanitizer: heap-buffer-overflow on address

szczególnie w kodzie który ma zero związku z iteracją

Konstruktor tylko robi iterację, cała klasa w paru liniach tylko nie można by było tu zrobić operatora + i -; trzeba by było używać funkcji. A walidację dało by się zrobić w lambdach.

#include <iostream>
#include <algorithm>
#include <iterator>

int main()
{
    std::string normal("123");
    std::string BigNum;
    std::transform(normal.rbegin(), normal.rend(),
                    std::back_inserter(BigNum), 
                   [](unsigned char c) { return c-'0';});
    std::transform(BigNum.rbegin(), BigNum.rend(),
                     std::ostream_iterator<short>(std::cout, " "), 
                   [](unsigned char c) { return c;});
    std::cout<<std::endl;
    return 0;
}

strzałem w stopę

Osobiste doświadczenie. Po prostu nie do końca rozumiem referencję do kontenerów STL.

Nie raz mi referencja do kontenerów krwi napsuła, a już na pewno do stringa.

komentarz 14 lutego przez TOWaD Mądrala (6,000 p.)

@adrian17, Nawet za to jeszcze nie podziękowałem. Dzięki, dawno się tyle rzeczy nie dowiedziałem i to w dyskusji to nie to samo co przeczytać. Dużo bardziej zapada w pamięć.

Podobne pytania

0 głosów
1 odpowiedź 147 wizyt
pytanie zadane 30 marca 2020 w C i C++ przez Quegon23 Nowicjusz (150 p.)
0 głosów
2 odpowiedzi 315 wizyt
pytanie zadane 16 lutego 2019 w C i C++ przez niedzwiedz89 Nowicjusz (150 p.)
+2 głosów
2 odpowiedzi 603 wizyt
pytanie zadane 3 kwietnia 2017 w C i C++ przez Evelek Nałogowiec (28,960 p.)

92,579 zapytań

141,432 odpowiedzi

319,663 komentarzy

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

...