2010-09-06 17 views
7

Mam ponad milion rekordów, każdy z około 30 znaków nad gniazdem. Czy mogę przeczytać wszystko w jednym ciągu? Czy istnieje limit rozmiaru ciągu, który mogę przydzielić?limit rozmiaru łańcucha w C++?

Jeśli tak, to czy mogę przesłać dane przez rekordy gniazd przez rekord i odbierać je według rekordu. Nie znam wielkości każdego rekordu do czasu wykonania.

Odpowiedz

16

Aby odpowiedzieć na pierwsze pytanie: Maksymalny rozmiar C++ ciąg jest podana przez string::max_size

+4

Chociaż można wspomnieć, że w większości implementacji ten maksymalny rozmiar zasadniczo stanowi całą pamięć dostępną dla procesu. – Omnifarious

+0

Kiedy zobaczyłem max_size, pomyliłem go z ustawieniem max_size przez użytkownika, więc nieco bardziej pomocnym jest zobaczenie go jako programu: http://stackoverflow.com/questions/1521281/what-are-the-stl -string-limits? rq = 1 – Nav

2

Nie ma oficjalnego limitu rozmiaru napisu. Oprogramowanie poprosi twój system o pamięć i, o ile ją otrzyma, będzie mógł dodawać znaki do twojego ciągu znaków.

Reszta pytania nie jest jasna.

1

Teoretycznie nie. Ale nie przydzielaj 100 GB pamięci, ponieważ użytkownik prawdopodobnie nie będzie miał tak dużo pamięci RAM. Jeśli używasz std :: string, maksymalny rozmiar to std :: string :: npos.

4

Jedynym praktycznym ograniczeniem rozmiaru ciągu znaków w języku C++ jest dostępna pamięć. Biorąc to pod uwagę, będzie kosztowne, aby ponownie przydzielić twój ciąg znaków do odpowiedniego rozmiaru, ponieważ nadal otrzymujesz dane (zakładając, że nie znasz ich całkowitego rozmiaru z góry). Zwykle czytasz fragmenty danych w buforze o stałym rozmiarze i dekodujesz go w jego naturalnej formie (twoje rekordy) w miarę jego uzyskiwania.

8

std::string::max_size() powie Teoretyczny limit narzucony przez architekturę program jest uruchomiony pod. Poza tym, o ile masz wystarczającą ilość pamięci RAM i/lub miejsca na dysku, możesz mieć ogromny rozmiar. Odpowiedź na drugie pytanie brzmi: tak, możesz wysyłać rekord przez rekord, ponadto możesz nie być w stanie wysłać dużych porcji danych przez gniazdo jednocześnie - są ograniczenia wielkości pojedynczej operacji wysyłania. To, że rozmiar pojedynczego ciągu znaków nie jest znany, dopóki środowisko wykonawcze nie stanowi problemu, nie musi być znane podczas kompilacji, aby wysłać je przez gniazdo. Sposób wysyłania tych łańcuchów rekordów według rekordu zależy od używanej biblioteki gniazd/sieci; skonsultuj się z odpowiednią dokumentacją.

-1

Jeśli mówimy o char* Jesteś ograniczony z czymś o 2^32 na systemach 32-bitowych i 64 z 2^na (niespodzianka) te 64-bitowe

Aktualizacja: To jest złe. Zobacz komentarze

+0

dlaczego przestaje działać? –

+1

Nie padłem, ale mogę zrozumieć, jak ktoś może. Pomimo nazewnictwa, nie znam żadnego "64-bitowego" systemu, który faktycznie obsługuje wszędzie blisko 2^64 pamięci. Bieżące projekty procesorów są zwykle ograniczone do 2^42 bajtów pamięci (a większość płyt głównych do mniejszej). –

+0

Istnieje również problem fragmentacji pamięci - zakres adresów może nie być ciągły - i pytanie, czy wewnętrzne księgowanie operatora "operator new" może obsługiwać tak dużą blokadę pamięci. – MSalters

2

Wielkość napisu jest ograniczona jedynie ilością pamięci dostępnej dla programu, jest to raczej ograniczenie systemu operacyjnego niż ograniczenie C++. Łańcuchy C++/C mają wartość NUL zakończoną, więc procedury łańcuchowe z radością przetworzą bardzo długie łańcuchy, dopóki nie znajdą wartości pustej.

W systemie Win32 maksymalna ilość pamięci dostępnej dla danych wynosi zwykle około 2 gigabajty.

Możesz odczytywać dowolnie duże ilości danych z gniazda, ale musisz mieć jakiś sposób na wytyczenie danych, które czytasz. Konieczny jest koniec znacznika rekordu lub długości rekordu, który czytasz, użyj go do przeanalizowania rekordów. Czy naprawdę chcesz odczytać dane w ciągu znaków? Co się dzieje, jeśli nie masz wystarczającej ilości wolnej pamięci do przechowywania danych w pamięci RAM? Podejrzewam, że istnieje lepszy sposób na przetwarzanie tych danych, ale nie wiem wystarczająco dużo o tym problemie.

0

Co powiesz na przesłanie ich w innym formacie?

na swoim serwerze: send (strlen (szRecordServer)); send (szRecordServer);

w Tobie klient: recv (cbRecord); alloc (szRecordClient); recv (szRecordClient);

i powtórz to milion razy.