c++ segmentation fault tablica czterowymiarowa

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
easymen
Piegowaty Guziec
Piegowaty Guziec
Posty: 4
Rejestracja: 25 lis 2008, 12:13
Płeć: Mężczyzna
Wersja Ubuntu: 8.10
Środowisko graficzne: KDE Plasma

c++ segmentation fault tablica czterowymiarowa

Post autor: easymen »

Witam mam problem odnośnie c++, gdy próbuje za inicjować taką tablice cztery[49][49][49][49], program się kompiluje ale gdy go uruchomię wyskakuje błąd 'segmentation fault.
Mój komp to acer 3100+ 512 ram, jeśli macie jakieś pomysły to piszcie.
adrian5632
Przyjaciel
Przyjaciel
Posty: 259
Rejestracja: 17 gru 2006, 16:07
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: KDE Plasma

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: adrian5632 »

Pozostaje pytanie, jak ty tę tablicę inicjujesz i po co ci aż cztery wymiary?
[IMG]http://www.ubudsl.com/media/UbuDSL.png[/IMG]
Masz problem z UbuDSL? Nie zapomnij wygenerować i załączyć loga do postu!
mikolajs
Wytworny Kaczor
Wytworny Kaczor
Posty: 352
Rejestracja: 15 paź 2008, 18:30
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: KDE Plasma

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: mikolajs »

Obecnie tab[] nie jest już zwykłym wskaźnikiem tylko wbudowanym typem tablicowym, a obecnie istnieje tylko typ tab[][][], większego nie ma. Zatem musisz to zrobić dynamicznie np.:

Kod: Zaznacz cały

int**** tab4 = new int***[50];
   for (int i = 0; i < 50; i++) {
     tab4[i] = new int**[50];
     for (int j = 0; j < 50; j++) {
       tab4[i][j] = new int*[50];
       for (int k = 0; k < 50; k++) tab4[i][j][k] = new int[50];
       }
     }
Po wykorzystaniu analogicznie zwolnić pamięć!
Awatar użytkownika
el.pescado
Zakręcona Traszka
Zakręcona Traszka
Posty: 734
Rejestracja: 26 maja 2005, 11:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: el.pescado »

Taka tablica jest zbyt duża, by się mogła zmieścić na stosie. Pozostaje alokować ją na stercie, tak jak jest napisane wyżej. Można też zaalokować tablicę jednowymiarową o rozmiarze 49^4, i sprytnie obliczać indeksy.
easymen
Piegowaty Guziec
Piegowaty Guziec
Posty: 4
Rejestracja: 25 lis 2008, 12:13
Płeć: Mężczyzna
Wersja Ubuntu: 8.10
Środowisko graficzne: KDE Plasma

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: easymen »

Dziękuje za podpowiedzi, mój sprzęt jest za słaby na takie triki
ccl
Piegowaty Guziec
Piegowaty Guziec
Posty: 9
Rejestracja: 22 lis 2009, 13:52
Płeć: Mężczyzna
Wersja Ubuntu: 9.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: ccl »

easymen pisze:Dziękuje za podpowiedzi, mój sprzęt jest za słaby na takie triki
50^4*sizeof(int) = 6250000 * 4 = 25MB

Tyle ramu to chyba masz? ;)
easymen
Piegowaty Guziec
Piegowaty Guziec
Posty: 4
Rejestracja: 25 lis 2008, 12:13
Płeć: Mężczyzna
Wersja Ubuntu: 8.10
Środowisko graficzne: KDE Plasma

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: easymen »

'ccl' bardzo trafna uwaga, z początku też to liczyłem wychodziło mi 23MB ale nadal nie wiem gdzie tkwi problem. Próbowałem znaleść maksymalny rozmiar tablicy ktora sie kompiluje i wyszło mi unsigned short int tab[45][45][45][45] ; sizeof(tab)= 8201250=8,2MB , a może w ubuntu coś trzeba zmienić?
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: luzakwielki »

easymen pisze:'ccl' bardzo trafna uwaga, z początku też to liczyłem wychodziło mi 23MB ale nadal nie wiem gdzie tkwi problem. Próbowałem znaleść maksymalny rozmiar tablicy ktora sie kompiluje i wyszło mi unsigned short int tab[45][45][45][45] ; sizeof(tab)= 8201250=8,2MB , a może w ubuntu coś trzeba zmienić?
Gdybyś zrozumiał to co napisał el.pescado to wiedziałbyś o co chodzi (lub rozróżniał stos od sterty).
W skrócie nie rób statycznej tablicy o tak dużym rozmiarze, bo się nie mieści na stosie i alokuj ją dynamicznie na stercie (tak jak pokazał Ci mikolajs - patrz od "kod", bo wcześniej gada bzdury ;p)
Awatar użytkownika
PL_kolek
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 113
Rejestracja: 30 sty 2008, 21:46
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Openbox
Architektura: x86_64

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: PL_kolek »

A jakby taką wielką tablicę zadeklarować globalnie zamiast w ciele funkcji to by przeszło? Bo zawsze tak robiłem z gigantycznymi tablicami i problemu nie miałem.
mikolajs
Wytworny Kaczor
Wytworny Kaczor
Posty: 352
Rejestracja: 15 paź 2008, 18:30
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: KDE Plasma

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: mikolajs »

bo wcześniej gada bzdury ;p)
To prawda :(
Ale czy faktem jest że int tab[] != int *tab, czy może tu też się mylę?
A jakby taką wielką tablicę zadeklarować globalnie zamiast w ciele funkcji to by przeszło? Bo zawsze tak robiłem z gigantycznymi tablicami i problemu nie miałem.
chyba pomoże, ale nie warto. Naprawdę lepiej alokować dynamicznie, bo nawet jeśli u Ciebie zadziała (system znajdzie na stosie pamięć o ciągłej długości równej pojemności wszystkich danych) to u kogoś innego pamięć może być trochę mniejsza. W w przypadku podanym przez mnie potrzebna jest pamięć w mniejszych porcjach.
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: luzakwielki »

mikolajs pisze:Ale czy faktem jest że int tab[] != int *tab, czy może tu też się mylę?
tab[] to wskaźnik *tab (tab jest wskaźnikiem na początek zaalokowanej pamięci), tab[5] to dla kompilatora *(tab + 5) - dlatego też dla kompilatora wszystko jedno czy napiszesz tab[5] czy 5[tab] bo dodawanie jest przemienne ;p. W C/C++ tablice to po prostu ładniej opakowane wskaźniki.
Tablica wielowymiarowa np. 2wymiarowa to po prostu *(*(tab+i)+j) - tu też możesz użyć konstrukcji typu i[tab][j] co będzie równoznaczne z tab[j] (nie można zamienić z j bo wtedy już będzie zły wynik działań na wskaźnikach).
mikolajs
Wytworny Kaczor
Wytworny Kaczor
Posty: 352
Rejestracja: 15 paź 2008, 18:30
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: KDE Plasma

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: mikolajs »

tab[] to wskaźnik *tab (tab jest wskaźnikiem na początek zaalokowanej pamięci), tab[5] to dla kompilatora *(tab + 5) - dlatego też dla kompilatora wszystko jedno czy napiszesz tab[5] czy 5[tab] bo dodawanie jest przemienne ;p. W C/C++ tablice to po prostu ładniej opakowane wskaźniki.
Tablica wielowymiarowa np. 2wymiarowa to po prostu *(*(tab+i)+j) - tu też możesz użyć konstrukcji typu i[tab][j] co będzie równoznaczne z tab[j] (nie można zamienić z j bo wtedy już będzie zły wynik działań na wskaźnikach).

Oczywiście wszystko się zgadza!
Jednak typ jest inny (w starszych kompilatorach był identyczny).
Przykład:

Kod: Zaznacz cały

#include <iostream>
#include <typeinfo>
using namespace std;

int main() {
    int tab[10];
    int* wsk;
    wsk = tab;
    if (typeid(tab) == typeid(wsk)) cout << "Ten sam typ" << endl; 
    else cout << "Inny typ" << endl; //mają różne id 
    cout << sizeof(tab) << "\t" << sizeof(wsk)   <<"\t"<< sizeof (*wsk) << endl; //można sprawdzić rozmiar tablicy
    return 0;
}
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: c++ segmentation fault tablica czterowymiarowa

Post autor: luzakwielki »

mikolajs pisze: Jednak typ jest inny (w starszych kompilatorach był identyczny).
Wszystko zależy czy pytasz się jak to wygląda dla programisty niezależnie od kompilatora, czy od strony danej wersji kompilatora danej firmy (bo jak to zaimplementują jest już niezależne od języka i nie ma jednoznacznej odpowiedzi czy dla kompilatora jest to to samo czy nie (odpowiedź jest zależna od danego kompilatora) - jednak tak czy tak jest to wskaźnik (czy go opakują w klasę (w którego skład wchodzi wskaźnik i operator[], żeby nie pisać dodatkowej obsługi osobno dla tablic) czy nie (jest to po prostu wskaźnik i [] jest tłumaczony przed kompilacją jak w kompilatorach C) dalej jest to wskaźnik na miejsce w pamięci)).
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 9 gości