dynamiczne tablice - problem

0

Napisalem sobie taki programik (c++builder):
//--------------------------------------------------------------------------

//--------------------------------------------------------------------------

TForm1 *Form1;
int *t = NULL;
int ile=100000001;
//--------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
delete[] t;
t = new int[ile];
if(t == NULL) q->Caption="blad";
else q->Caption=IntToStr(t[100000000]);
}
//--------------------------------------------------------------------------

//--------------------------------------------------------------------------

Teoretycznie gdyby tablica się zarezerwowala :-) , to w polu textowym q
powinienem otrzymać jakąś
bliżej niezidentyfikowaną liczbę, a gdyby sie nie udalo to wyswietlilby sie
napis blad.

I rzeczywiście dla tablicy ile=1 000 001, wartość t[1 000 000] jest jakąś
tam liczbą - istnieje.
Ale dla t ile=1 000 000 01 nie ma już miejsca, a w polu q nie wyswietla sie
"blad",
lecz wywala sie błąd w okienku :-) : "Project1.exe raised exception class
bad_alloc" a debugger zaznacza linijkę
t = new int[ile];.

Jak sie przed tym zabezpieczyć? Probowalem to zrobic na wyjątkach, ale też
nic z tego.
Dobrze by bylo znalezc sposob na podanie konkretnej komorki tablicy, przy
ktorej konczy sie pamięć - ale jak, skoro tu sie taki syf robi???

Może by ktos podał jakiś przykladowy dzialający kod............

W innej sytuacji dzieje się znowu tak że tablica nie tworzy się do końca, a
wskaźnik nie jest null (i debugger sie już nie czepia linijki gdzie tablica
sie rezerwuje) ale za to bląd pojawia się przy probie odwolania do
konkretnego elemenyu tablicy.......

Pozdro

0

nieczytalem dokladnie, ale z tego co piszesz to odowlujesz sie do niestniejacego obszaru i debugger ma racje... ;)

w c/c++ indeksowanie tablic jest od zera, a nie jak w pasclu od 1. wiec komorka 1000...01 nie istnieje, ostatnia komorka to 1000..00 liczac od zera...

0

Po pierwsze zmienił bym linijke:
<font color="green">delete[] t;</span>
na
if(t) delete[] t;

Przy pierwszym kliknieciu na przycisk wystąpi sytuacja gdzie dla t nie będzie przydzielona jeszcze pamięć, a ty juz starasz się ją zwolnic.

Co do reszty to nie mam pojęcia, ale mozliwe jest, ze kompilator nie zezwala na przydzielanie takiej ilosci pamięci.
Weź pod uwage że:

int = 4 bajty

4*100000001=400000004 bajtów
co daje około 390625 kb -> 381,5 mb !!

0

Udało mi się rozwiązać problem za pomocą try, catch.
Wcześniej zostałem wprowadzony w błąd przez debugera, ktory wywalał błędy pomimo try i catch.... :-/

Teraz jest jeszcze sprawa określenia max rozmiaru tablicy, przy którym nie brakuje pamięci.
Robie to tak, że po wychwyconym braku pamięci dzielę rozmiar tablicy przez 2 i znowu proboje zrobić tablice. Jeśli jest blad, to znowu to samo, a jeśli nie to od wartości przy której na początku wystąpił błąd odejmuję jej połowę i znowu dzielę i próbuję rezerwować pamięć..... :-) .

Może ktos ma lepszy pomysł........ [???] :-)

Pozdrawiam

0

Po co dzielić ?
Wystarszy pomnozyc razy 1/2 ;-) :-D

0

Na moje oko to zwykły błąd przepełnienia. Bo int to -32000..32000(chyba) czyli podajać 100000000 robisz przepełnienie, czyli jak podasz 100000001 to najwidoczniej występuje owe przepełnienie i zakres liczony jest od nowa, czyli -32000.

0

neeeeeeeee
to Ty o jakimś małym incie mowisz.
Te "zwykłe" mają od -2 147 483 648 do 2 147 483 647

0

Nie prościej użyć: GlobalMemoryStatus ? :)

0

Dzięki wszystkim za wszystkie odpowiedzi.........

[browar]
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1