Uszkodzenie sterty podczas zwalniania dynamicznej pamięci
Ostatnio zmodyfikowano 2018-08-17 20:59
Gowers Temat założony przez niniejszego użytkownika |
Uszkodzenie sterty podczas zwalniania dynamicznej pamięci » 2018-08-17 15:54:02 Witam, robię zadania ze spoja, które ma pobierać dwa łańcuchy znaków , przekazywać je do funkcji i zwracać wskaźnik na dynamicznie zaalokowaną pamięć. Wszystko działa, ale gdy zwalniam pamięć w mainie przez delete[] text wyskakuje mi komunikat "uszkodzenie sterty". Mógłby mi ktoś to wytłumaczyć? Bo nie potrafię sam tego zrozumieć. Funkcja chyba zwija stertę po zakończeniu tak? Ale z utworzoną pamięcią w niej przez operator new co się dzieje? Zostaje przecież? Domyślam się, że problem leży w tym że pamięć tworzę w funkcji, a zwalniam ją w mainie? #include<iostream> #include<limits> #include<string> using namespace std;
char * string_merge( char *, char * );
int main() { string firstText; string secondText; int t; int counter = 0; while( 1 ) { cout << "Podaj ilosc: "; cin >> t; if( t > 0 && !cin.fail() ) break; else if( cin.fail() ) { cin.clear(); cin.ignore( numeric_limits < streamsize >::max(), '\n' ); } } while( counter < t ) { cout << "Podaj dwa lancuchy znakow: "; cin >> firstText >> secondText; char * a = & firstText[ 0 ]; char * b = & secondText[ 0 ]; char * text = string_merge( a, b ); cout << text << endl; delete[] text; counter++; } cout << endl; system( "pause" ); return 0; }
char * string_merge( char * a, char * b ) { char * text = nullptr; int counter = 0; int iteratorA = 0; int iteratorB = 0; if( strlen( a ) <= strlen( b ) ) { text = new char[ 2 * strlen( a ) ]; while( counter < 2 * strlen( a ) ) { if( !( counter % 2 ) ) { text[ counter ] = a[ iteratorA ]; if( counter != 0 ) iteratorB++; } else { text[ counter ] = b[ iteratorB ]; iteratorA++; } counter++; } } else { text = new char[ 2 * strlen( b ) ]; while( counter < 2 * strlen( b ) ) { if( !( counter % 2 ) ) { text[ counter ] = a[ iteratorA ]; if( counter != 0 ) iteratorB++; } else { text[ counter ] = b[ iteratorB ]; iteratorA++; } counter++; } } text[ counter ] = '\0'; return text; }
|
|
mateczek |
» 2018-08-17 16:10:07 cout << "Podaj ilosc: "; co to za zadanie ?? W spoju pomijasz komunikaty. Sprawdzarka dostarcza Ci strumień danych wejściowych i ty musisz odpowiedzieć strumieniem danych wyjściowych. Nie ma tam miejsca na wymyślone komunikaty typu podaj ilość. |
|
Gowers Temat założony przez niniejszego użytkownika |
» 2018-08-17 16:11:44 Komunikat jest dla mnie, żebym się orientował gdzie dokładnie jestem w programie. Wszystko niepotrzebne potem kasuje. To nie jest ostateczna wersja. To zadanie https://pl.spoj.com/problems/PP0504B/ ale robię je na własnym kodzie. |
|
Monika90 |
» 2018-08-17 16:26:23 W twojej dynamicznie alokowanej tablicy nie ma miejsca na znak '\0'. Tak więc ta instrukcja text[ counter ] = '\0'; zapisuje poza tablicą. |
|
Gowers Temat założony przez niniejszego użytkownika |
» 2018-08-17 16:29:19 Dziękuję za pomoc |
|
pekfos |
» 2018-08-17 16:30:30 Przekraczasz zakres tablicy. Poza tym.. Nie wywołuj bez przerwy strlen(), podnosisz przez to złożoność obliczeniową do kwadratowej. I dlaczego w ogóle ręcznie zarządzasz pamięcią? Było by znacznie prościej operować na std::string, bo i tak już używasz std::string. |
|
mateczek |
» 2018-08-17 16:31:56 char * a = & firstText[ 0 ]; const char * tablicaChar = firstText.c_str();
Spoj i tak sprawdzi Ci wynik końcowy. Więc skoro robisz na stringach to możesz dokończyć na stringach wszelkie cin.fail, cin.ignore, Do wywalenia na spoju nie możesz pomijać danych no i autor zadania w treści umieścił funkcję main i kazał dopisać funkcję merge |
|
pekfos |
» 2018-08-17 16:37:02 Zadanie podaje taki kod? Bad design. Na dobrą sprawę, nie trzeba w ogóle alokować żadnej pamięci char * text = string_merge( a, b ); cout << text << endl; delete[] text;
|
Po prostu wypisuj na zmianę po jednym znaku z obu napisów, skoro i tak łączysz napisy tylko po to, by je wyświetlić. |
|
« 1 » 2 |