Sprawdzenie zwrotu malloc
nie pomaga samemu, aby twoje alokacje były bezpieczniejsze lub mniej podatne na błędy. Może to być nawet pułapka, jeśli jest to jedyny test, który zastosujesz.
Po wywołaniu z argumentem 0
standard zezwala na to, aby malloc
zwrócił unikalny adres, który nie jest wskaźnikiem zerowym, a do którego użytkownik nie ma prawa dostępu. Jeśli więc po prostu przetestujesz, czy zwrot jest 0
, ale nie przetestuj argumentów na malloc
, calloc
lub realloc
, możesz natrafić na błąd segfault znacznie później.
Ten błąd (pamięć wyczerpana) występuje dość rzadko w środowiskach "hostowanych". Zwykle masz kłopoty na długo przed tym, zanim natkniesz się na ten rodzaj błędu. (Ale jeśli piszesz biblioteki uruchomieniowe, jesteś hakerem jądra lub konstruktorem rakiet, to jest inaczej i tam test ma sens).
Ludzie mają tendencję do ozdabiania swojego kodu skomplikowanymi chwytami tego błędu, który obejmuje kilka linie, robienie perror
i podobne rzeczy, które mogą mieć wpływ na czytelność kodu.
Myślę, że to "sprawdź powrót malloc
" jest znacznie zawyżone, czasami nawet bronione dość dogmatycznie. Inne rzeczy są znacznie ważniejsze:
- zawsze inicjalizuj zmienne, zawsze. dla zmiennych wskaźnika jest to kluczowe, niech program się psuje, zanim wszystko pójdzie źle. niezainicjowani członkowie wskaźnika w numerach
struct
są ważną przyczyną błędów, które są trudne do znalezienia.
- zawsze sprawdzić argument
malloc
and Co., czy jest to stała czas kompilacji jak sizof toto
nie może być problemem, ale zawsze upewnić się, że przydział wektor obsługuje sprawę właściwie zerowe.
Łatwo sprawdzić pod kątem powrotu malloc
jest opakować coś podobnego do memset(malloc(n), 0, 1)
. To po prostu zapisuje 0
w pierwszym bajcie i ładnie się zawiesza, jeśli malloc
miał błąd lub na początku był.
Myślę, że nie powinieneś używać malloc w C++: http://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-vs-new – lc2817
@ lc2817 powinieneś używać tylko malloc, jeśli piszesz kod z interfejsem C (tj. funkcje, które mają być używane z C, ale napisane w C++) ** i ** kod C jest odpowiedzialny za uwolnienie tej pamięci. –
@WTP dzięki za tę precyzję. Chociaż nie wiem, czy tak jest w tym przypadku. – lc2817