2013-07-08 12 views
5

Używam C przez jakiś czas i mam ten banalny problem, o który chcę zapytać.Zawiera znak null podczas przydzielania przy użyciu malloc

Powiedz, że chcę utworzyć tablicę znaków, która przechowuje do 1000 znaków. Teraz, gdy używam malloc dla tego samego, to czy mogę określić rozmiar tablicy jako 1001 znaków [1000 znaków + null] lub tylko 1000?

Powiedzmy, że natknąłem się na ten problem, więc jak mógłbym znaleźć odpowiedź na to rozwiązanie na własną rękę, być może za pomocą niektórych programów testowych. Rozumiem, że rozmiar łańcucha znaków jest obliczany bez znaku pustego, ale kiedy przydzielam pamięć dla tego samego, czy biorę pod uwagę także znak zerowy?

Odpowiedz

7

Jeśli potrzebujesz tego bloku do przechowywania łańcucha zakończonego znakiem NUL, to tak, musisz wyraźnie poprosić malloc(), aby przydzielić dodatkowy bajt do przechowywania terminatora o wartości NULL, malloc() nie zrobi tego dla ciebie inaczej. Jeśli zamierzasz przechowywać długość łańcucha gdzieś indziej, a więc nie potrzebujesz terminatora zerowego, możesz uciec bez przydzielania dodatkowego bajtu.Oczywiście od Ciebie zależy, czy potrzebujesz ciągów znaków dla zakończenia null, ale nie zapominaj, że funkcje obsługi łańcuchów bibliotek C działają tylko z zakończonymi znakami NUL łańcuchami.

1

Rzeczywiście należy przydzielić pamięć dla terminatora o wartości NULL.

Konceptualnie terminator zerowy jest po prostu wygodnym sposobem oznaczania końca ciągu. Biblioteka standardowa C wykorzystuje tę konwencję podczas modelowania łańcucha. Na przykład strlen oblicza długość łańcucha przez zbadanie pamięci z lokalizacji wejściowej (prawdopodobnie char *), dopóki nie osiągnie terminatora zerowego; ale sam terminator o wartości null nie jest uwzględniany w długości. Ale nadal jest to część pamięci zużywanej przez ciąg.

1

Od Ciebie zależy, czy podasz postać kończącą zero.

przydziela pamięć dla ciebie, ale nie ustawia jej na nic.

Jeśli otrzymasz strcpy do przydzielonej pamięci, będziesz miał do dyspozycji terminator kończący.

Alternatywnie, użyj calloc, ponieważ ustawi ona wszystkie elementy na 0, co w efekcie jest znakiem zerującym. Jeśli tak, powiedzmy, memcpy, nie będziesz musiał się martwić o prawidłowe zakończenie ciągu.

+2

Nadal musisz wziąć pod uwagę, że terminator zerowy potrzebuje dodatkowego bajtu, więc jeśli twój ciąg ma mieć długość tysiąca znaków, użycie 'calloc()' nie zmienia faktu, że potrzebujesz tysiąc i jeden bajt do przechowywania ciągu znaków. –

2

malloc i rodzina przydziela pamięć w porcjach bajtów. Więc jeśli zrobisz malloc(1000), otrzymasz 1000 bajtów. malloc nie będzie obchodzić, czy przydzielono te 1000 bajtów do przechowywania ciągu znaków lub dowolnego innego typu danych.

Ponieważ łańcuchy w C składają się z jednego bajta na znak i najlepiej muszą być zakończone zerem, musisz upewnić się, że masz wystarczająco dużo pamięci, aby to pomieścić. Tak więc odpowiedź brzmi: Tak, musisz przydzielić 1001 bajtów, jeśli chcesz przechowywać ciąg 1000 znaków plus zero.

Wskazówka: pamiętaj, że w zależności od tego, jak go używasz, możesz zakończyć zerowanie ciągu znaków, ale nie musi.

Jeśli na przykład znać dokładną długość łańcucha można określić, że podczas używania go z printf

printf("%*s", length, string); 

zostanie wydrukowany dokładnie length znaków z bufora wskazał na string.

Powiązane problemy