Bimbol Temat założony przez niniejszego użytkownika |
Problem z dynamiczną dwuwymiarową tablicą. » 2013-07-20 14:38:22 Witam, mimo, że poprzedni problem został rozwiązany. To po około 30 razy bez problemowych testów, później znów program się posypał. Tym razem nie ma Segmentation Fault , lecz podczas Debugowania mam inny komunikat Program received signal SIGTRAP, Trace/breakpoint trap. . Dodam, że wyskakuje on nie dla wszystkich wartości. Szukałem rozwiązania na Google, jednak nic nie znalazłem. main.cpp: #include "array.h"
int main() { CIntArrayDouble Test( 3, 3 ); Test.ChangeSize( 1, 10 ); for( unsigned i = 0; i < Test.GetIndexSize1(); ++i ) for( unsigned j = 0; j < Test.GetIndexSize2(); ++j ) Test.SetValue( i, j, i + j ); for( unsigned i = 0; i < Test.GetIndexSize1(); ++i ) for( unsigned j = 0; j < Test.GetIndexSize2(); ++j ) cout << Test.GetValue( i, j ) << endl; return 0; } array.h: #ifndef ARRAY_H_INCLUDED #define ARRAY_H_INCLUDED
#include <iostream> #include <memory.h>
using namespace std;
class CIntArrayDouble { private: int ** m_Table; unsigned m_Index1; unsigned m_Index2; public: CIntArrayDouble( unsigned Index1, unsigned Index2 ) : m_Index1( Index1 ) , m_Index2( Index2 ) { m_Table = new int *[ m_Index1 ]; for( unsigned i = 0; i < m_Index1; ++i ) m_Table[ i ] = new int[ m_Index2 ]; } ~CIntArrayDouble() { for( unsigned i = 0; i < m_Index1; ++i ) delete[] m_Table[ i ]; delete[] m_Table; } int GetValue( unsigned Index1, unsigned Index2 ) { if( Index1 > m_Index1 || Index2 > m_Index2 ) return - 1; return m_Table[ Index1 ][ Index2 ]; } bool SetValue( unsigned Index1, unsigned Index2, int value ) { if( Index1 > m_Index1 || Index2 > m_Index2 ) return false; m_Table[ Index1 ][ Index2 ] = value; return true; } unsigned GetIndexSize1() { return m_Index1; } unsigned GetIndexSize2() { return m_Index2; } void ChangeSize( unsigned Index1, unsigned Index2 ) { int ** Array = new int *[ Index1 ]; for( unsigned i = 0; i < Index1; ++i ) Array[ i ] = new int[ Index2 ]; if( Index1 > m_Index1 ) memcpy( Array, m_Table, sizeof( int ) * m_Index1 ); else memcpy( Array, m_Table, sizeof( int ) * Index1 ); m_Table = Array; m_Index1 = Index1; m_Index2 = Index2; } };
#endif
Na prawdę nie mam już pojęcia o co chodzi. |
|
pekfos |
» 2013-07-20 14:45:28 if( Index1 > m_Index1 || Index2 > m_Index2 ) return - 1;
|
Powinno być >=. |
|
Bimbol Temat założony przez niniejszego użytkownika |
» 2013-07-20 14:51:31 Faktycznie, taki głupi i niewinny błąd. Mimo wszystko wciąż jest ten sam problem dla niektórych wartości. Przykładowo dla Test.ChangeSize( 2, 5 ); nie działa, a dla Test.ChangeSize( 4, 2 ); działa bez zarzutów. |
|
pekfos |
» 2013-07-20 14:59:42 Zamiast wartości z tablicy kopiujesz wskaźniki na drugi wymiar. Dodatkowo nie zwalniasz starej tablicy. |
|
Bimbol Temat założony przez niniejszego użytkownika |
» 2013-07-20 15:02:03 Czyli jak to powinno wyglądać? Gdy zwalniam starą tablice, wyświetla błędne wartości.
Testowałem kopiowanie w funkcji main.cpp i wszystko działał w sposób, który to robiłem. Również takie rozwiązanie znajduje się w kursie, który aktualnie przerabiam.
Hmm.. jeśli jest to źle to jak to powinno wyglądać? |
|
pekfos |
» 2013-07-20 15:09:51 Wyjaśnię, co robisz (aktualnie i źle): 1. Alokujesz nową tablicę dwuwymiarową - tu jest jeszcze ok 2. Sprawdzasz tylko pierwszy rozmiar i kopiujesz tylko wskaźniki na stare tablice (o starym drugim rozmiarze!) 3. Aktualizujesz zmienne z rozmiarami, które mogą być niezgodne z faktycznymi rozmiarami tablic. Do tego kopiując wskaźniki zastępujesz te, wskazujące na nowo zaalokowane bloki. W efekcie jeśli zwiększasz pierwszy rozmiar i zmieniasz drugi, to pierwsze n (stary pierwszy rozmiar) tablic będzie miało stary rozmiar, a tylko nowo dodane tablice będą miały nowy rozmiar. |
|
Bimbol Temat założony przez niniejszego użytkownika |
» 2013-07-20 16:36:52 Cóż, przerobiłem nieco metodę zmiany długości tablicy. void ChangeSize( unsigned Index1, unsigned Index2 ) { int ** Array = new int *[ Index1 ]; for( unsigned i = 0; i < Index1; ++i ) Array[ i ] = new int[ Index2 ]; for( unsigned i = 0; i < Index1; ++i ) { memcpy( Array[ i ], m_Table[ i ], sizeof( int ) * Index2 ); delete[] m_Table[ i ]; } memcpy( Array, m_Table, sizeof( int ) * Index1 ); delete[] m_Table; m_Table = Array; m_Index1 = Index1; m_Index2 = Index2; } Jednak występuje teraz Segmenation Faul, w Dekonstruktorze. |
|
pekfos |
» 2013-07-20 16:44:04 Teraz gdy zwiększasz drugi rozmiar wychodzisz poza tablicę przy kopiowaniu i dalej kopiujesz stare wskaźniki.. Segmenation Faul, w Dekonstruktorze. |
Fault, destruktorze. |
|
« 1 » 2 |