Jak dużo można zaalokować pamięci??

0

Witam!!
Jaki jest limit dla dynamicznej alokacji pamięci za pomocą malloc lub new.

Napisałem sobie coś takiego żeby sprawdzić

#include <iostream>

int main(void)
{
	int *temp;
	int tab[10];
	int rozmiar = 1;

	temp = (int*)malloc(sizeof(int) * rozmiar);
	if (temp == NULL)
		return 0;

	while (1)
	{
		rozmiar += 1000000;
		temp = (int*)realloc(temp, sizeof(int) * rozmiar);
	}

	return 0;
}

i po paru sekundach error "Invalid allocation size 4294967295 bytes".
jest to maksymalny rozmiar alokacji dla jednej tablicy??
przekroczyłem teraz rozmiar sterty??
da się to jakoś obejść ??

3

Możesz zaalokować tylko tyle ile Ci implementacja pozwoli :)
Są dwa ograniczenia:

  1. ile pamięci system operacyjny pozwoli przydzielić (nie musi być to wartość zgodna z ilością pamięci w sprzęcie, ale nie użyjesz więcej niż masz, oczywiście)
  2. wielkość wskaźnika. W aplikacji 32-bitowej nie możesz zaadresować więcej niż 2³² bajtów i już.
0

dla maszyny 32 bity mam maksymalnie to alokacji dla pojedynczej zmiennej to 4294967295 bity(bo tyle jes dziesiętnie 32 jedynki obok siebie)
a dla maszyny 64 bit maksymalnie dla jednej zmiennej to 9223372036854775807(bo tyle jest dziesiętnie 63 jedynki koło siebie )
a 64 jedynki po zamianie na dzsiętny daje -1 i dlatego ten error miałem bo nie moge dać ujemnej wartość do alokowania
i jest jeszcze typ unsigned który pozwoli mi jeszcze wicej wziąć bo nibędzie potrzeba tego jednego bitu na znak

dobrze to rozumiem??

1

Nie. Nie myl bitów adresu z bajtami do alokacji. Możesz zaalokować tyle pamięci ile możesz zaadresować wskaźnikiem. Na 32 bitach wskaźnik ma 32 bity więc maksymalna liczba jaką przechowuje to 232 więc tyle komórek pamięci możesz zaadresować. Jeśli wskaźnik ma 64 bity to możesz zaadresować 264 komórek. I nie "dla pojedyńczej zmiennej" tylko w ogóle. Program nie może zaalokować więcej pamięci bo zwyczajnie nie miałby jak sie do niej odnosić.

0
#include <iostream>
#include <climits>

int main(void)
{
	unsigned long long int *temp;

	temp = (unsigned long long int *)malloc(18446744073709551615);
	if (temp == NULL)
	{	
		std::cout << "błąd alokacji" << std::endl;
		int x;
		std::cin >> x;
	}

	std::cout << "poprawna alkoacja  " << std::endl << "Zakresy: " << ULLONG_MAX << " ||  " << INT_MAX << std::endl;
	int x;
	std::cin >> x;

	return 0;
}

ULLONG_MAX wynosi 18446744073709551615 i niejestem wstanie tego zaalokować mimo że typ jest unsigned long long int
kieruje się tym http://www.cplusplus.com/reference/climits/

3

O RLY? A masz 16 petabajtów pamięci? o_O

0

no ale wpisałem przecież rozmiar jaki można odczytać z bibliteki climits więc co źle zrobiłem?

5
jibril napisał(a):

no ale wpisałem przecież rozmiar jaki można odczytać z bibliteki climits więc co źle zrobiłem?

Masz metr sznurka. Możesz sobie go podzielić na odcinki o dowolnej długości. Ułóż z nich odcinek o długości 100 km.

0

@jibril zapomniałeś użyć mózgu. Czym innym jest limit alokacji wynikający z mozliwości adresowania a czym innym fizyczne możliwości twojego komputera! Wyobraź sobie że masz w domu 100 szufladek, każda mieści jednego cukierka. To jest przestrzeń adresowa. Masz w ręku 10 cukierów, to jest twój RAM w komputerze.
Próbujesz teraz wkładać cukierki do szufladek. Górny limit cukierów które możesz włożyć to 100 (górny limit pamięci do zaalokowania wynika z rozmiaru wskaźnika, 32 lub 64 bity). Ale skoro masz tylko 10 cukierów to siłą rzeczy nie jesteś w stanie włożyć cukierka do wszystkich 100 szufladek. Rozumiesz? A ty nam tu piszesz że sprawdziłeś i szufladek jest 100 i czemu coś ci nie działa ;]

0

wiem o co ci chodzi, ale jak to się odnosi do mojego kodu.

Podaje w malloc ręcznie rozmiar typu unsigned long long int, i twierdzi że jest źle ale dlaczego??
chce zablokować tyle ile jest potrzebne na pojedynczą zmienną tego typu.

Moge ją stworzyć niedynamicznie więc dynamicznie tez na pewno się da.

0

Co ty bierzesz chłopie? Rozmiar typu long long int to sizeof(long long int) i wynosi 32 albo 64 bity, czyli 4 albo 8 bajtów. A ty podałeś w mallocu największą możliwą liczbę którą może przechować unsigned long long. Ty poprosiłes system operacyjny o zaalokowanie 16 petabajtów pamięci! Bo wyobraź sobie że argumentem malloc jest liczba bajtów które chcesz zaalokować.

0

aha czyli liczba bajtów ile wynosi zmienna, czyli u mnie 8 :D

no to jak mam taki błąd error "Invalid allocation size 4294967295 bytes"

4294967295 : 8 = 536870911,875;

więc moge mieć tablice tylu elementową tak 536870911 ??

0

Jeśli dostałeś taki błąd to znaczy ze masz 32 bitowy system operacyjny, tak? Bo to błąd przy alokacji 4GB pamięci. Jeśli masz w komputerze przynajmniej 4GB wolnej pamięci to tak, istnieje szansa że będziesz mógł tyle zaalokować, chociaż różnie bywa. Bo to musi być ciągły blok pamięci.

0

mam 4gb w całości a nie wolnego

0

Wiesz w ogóle co to jest system dwójkowy, co to jest bit i bajt? Bo wydaje mi się że mylisz wartość liczbową z ilością bitów na których można ją przedstawić. Na przykład do przedstawienia liczby 24896 nie potrzeba 24896 bitów tylko 16 (0110 0001 0100 0000) czyli 4 bajtów, 1 bajt to 8 bitów jakbyś jeszcze nie skumał.

0

@jibril lol no to o co w ogóle chodzi? Rozumiesz chyba że nie możesz w takim razie zaalokować 4GB? ;] Bo zapewne wolnego i dostępnego to masz teraz z 2 może 2,5...

0

już kminie malloc pryzmuje liczbę bajtów, a nie bitów, a co do ilości jestem ograniczany tym co jest akurat wolne na konkretnym sprzęcie

i ten błąd mi zgłasza visual studia 2013 a dev go nie zgłasza

0

Bo nie musi. malloc zwróci NULL i tyle

On success, a pointer to the memory block allocated by the function.
The type of this pointer is always void*, which can be cast to the desired type of data pointer in order to be dereferenceable.
If the function failed to allocate the requested block of memory, a null pointer is returned.

0

ok, dzięki

0

@Shalom
Pytanko bo ja chyba mam zaległości jakieś. Wcześniej pisałem post, ale coś mi nie pasowało, a mianowicie:

Invalid allocation size 4294967295 bytes

Wiem, że mam 4GB wirtualnej pamięci i 2GB idzie na kernel(można to ścisnąć ale po co), więc zostaje nawet nie całe 2GB dla mnie, kompilator wywalił ten błąd z "invalid allocation" bo przekroczyła jego przestrzeń jaką zarezerwował dla wskaźnika 4GB(przez tą myśl skasowałem posta), czy jak mi teraz wpadło bardziej logiczne, że to program przekroczył 4GB. Muszę spytać dla 100% pewności :P

0
  1. Nie kompilator tylko system operacyjny, bo program sie skompiluje i wysypie w runtime...
  2. Program, bo generalnie mamy przecież coś takiego jak wirtualną przestrzeń adresową. Każdy program ma tak jakby "swoje" adresy. Mozesz mieć dwa programy działające równolegle i w obu mieć wskaźniki o tych samych adresach ale w rzeczywistości pokazujące na zupełnie inne obszary pamięci.
0
  1. Wiem moja pomyłka wynikająca z szybkiego pisania, nawet autor napisał wątku pisał, że w runtime(pośrednio).
  2. Wystarczyło, że program, bo reszte wiem. Wysypie się on podczas alokacji, ale po prostu, wcześniej jak patrzałem na ten wątek miałem pierwszą myśl nie wiem skąd, że to wywala błąd aka "właśnie program próbował zaalokować 4GB pamięci" = "Invalid allocation size 4294967295 bytes" a to jednak, że program przekroczył. I zmylił mnie ten co pierwszy się wypowiadał, że mamy do użytku 4GB(możemy zaalokować). Dopiero przed chwilą jak znowu zajrzałem w ten wątek coś mnie tchnęło...
3
jibril napisał(a):

już kminie malloc pryzmuje liczbę bajtów, a nie bitów, a co do ilości jestem ograniczany tym co jest akurat wolne na konkretnym sprzęcie

tak, ale nie chodzi tylko o pamięć RAM i wcale nie jest to takie różne na każdym komputerze

aplikacje mają przydzieloną pamięć wirtualną
pamięć wirtualna likwiduje problemy z fragmentacją pamięci fizycznej - normalnie gdyby odpalono program zajmujący 1GB, potem 2GB, a potem zwolniono ten pierwszy program to wprawdzie zostało by 2GB wolnej pamięci ale byłaby ona podzielona na dwie części - jedna na początku, druga na końcu
przez takie coś niemożliwe byłoby zaalokowanie ciągłego bloku pamięci - trzeba by było pamiętać że blok (czy tablica) się kończy w danym miejscu i od tego miejsca trzeba przeskoczyć do innego - to komplikuje program

problem ten ma rozwiązać pamięć wirtualna - każda aplikacja 32 bitowa dostaje "wirtualne" 4GB niby do użytku w całości dla siebie i w numeracji liniowej od zera
dostaje 4GB niezależnie od tego ile jest dostępne w systemie; czy masz w komputerze 512MB RAMu czy 16GB - zawsze proces dostanie całe 4GB
przy uruchomieniu 20 programów oznacza to że w sumie mają do użytku 80GB, a w praktyce gdyby wszystkie nagle zaczęły być pazerne na pamięć to ta zaraz by się skończyła - to coś jak nieograniczone skrzynki pocztowe na wp.pl - niby nie mają limitu, ale wiadomo że cała idea bazuje na tym że przeciętnie użytkownik zajmuje zaledwie kilkadziesiąt MB

a więc każdy proces dostaje 4GB, z tego 2GB jednak tylko 2GB są do użytku programisty - resztą zajmuje się kernel
pamięć ta jest już jednak na starcie częściowo zajęta przez dll-ki które podczas wczytywania alokują i dealokują pamięć pozostawiając luki - tak samo jak w przypadku pamięci fizycznej - tak samo pamięć wirtualna się w ten sposób niestety fragmentuje
przydałoby się wprowadzić pamięć wirtualną w pamięci wirtualnej, ale zamiast tego wykorzystuje się chociażby listy - które nie potrzebują stałego, ciągłego bloku pamięci a tylko każdy element pamięta adres kolejnego (alokują wiele małych fragmentów) - w ten sposób można wykorzystać całą dostępną pamięć do ostatniego bajta

w praktyce po uruchomieniu programu można się spodziewać ciągłego bloku pamięci wirtualnej o rozmiarze około 1500MB
i tyle też można wpisać maksymalnie w malloc przy aplikacji 32 bitowej co na każdym komputerze powinno się udać

i tak - możesz zająć 1500MB pamięci nawet jeżeli w komputerze masz tylko 512MB RAMu, a wolnej pamięci masz zaledwie 1MB; bo o ile nie uruchamiasz swojej aplikacji pod DOSem lub użytkownik ręcznie tej opcji nie wyłączył to wirtualizacja pamięci skorzysta z pliku wymiany, a więc rolę brakującej pamięci fizycznej spełni dysk twardy

0
kq napisał(a)
  1. wielkość wskaźnika. W aplikacji 32-bitowej nie możesz zaadresować więcej niż 2³² bajtów i już.

Dobrze napisałeś: zaadresować.
Pod Windows używając przeznaczonych do tego funkcji WinAPI 32-bitowy program może zaalokować więcej niż 2³² B, ale w danym momencie może z tego adresować do 2³² bajtów.

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