Sprawdzanie niepowodzenia alokacji
Część sekcji Logika i sterowanie przepływem ścieżki C w Coddy. Lekcja 34 z 63.
Chociaż malloc() jest potężnym narzędziem do dynamicznego przydzielania pamięci, musisz zrozumieć pewną kluczową kwestię: malloc() może zawieść. Gdy w systemie zabraknie dostępnej pamięci, malloc() nie może spełnić Twojej prośby i zamiast prawidłowego adresu pamięci zwraca NULL.
Oznacza to, że za każdym razem, gdy używasz malloc(), musisz sprawdzić, czy się powiodło, zanim spróbujesz użyć zwróconego wskaźnika. Użycie wskaźnika NULL spowoduje awarię programu z powodu błędu segmentacji.
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // Zakończ program lub obsłuż błąd
}
// Można tu bezpiecznie używać ptr
*ptr = 42;To sprawdzenie NULL nie jest opcjonalne — jest niezbędne do pisania odpornych programów w C. Nawet jeśli błędy alokacji pamięci są rzadkie we współczesnych systemach, mogą się zdarzyć, zwłaszcza w środowiskach o ograniczonych zasobach lub przy żądaniu dużej ilości pamięci. Profesjonalny kod w C zawsze zawiera takie sprawdzenia, aby zapobiegać awariom i zapewniać łagodne obsługiwanie błędów.
Wyzwanie
ŁatwyNapisz program w C, który demonstruje prawidłową obsługę błędów podczas używania malloc() do dynamicznej alokacji pamięci. Twój program powinien:
- Wczytać od użytkownika liczbę całkowitą
n, określającą liczbę liczb całkowitych do przechowania - Użyć
malloc()wraz zsizeof(), aby dynamicznie przydzielić pamięć na tablicęnliczb całkowitych - Sprawdzić, czy alokacja pamięci się powiodła, testując, czy zwrócony wskaźnik ma wartość
NULL - Jeśli alokacja się nie powiedzie, wypisać
Memory allocation failed!i zakończyć program - Jeśli alokacja się powiedzie, wypisać
Memory allocation successful! - Wczytać od użytkownika
nliczb całkowitych i zapisać je w przydzielonej tablicy - Obliczyć i wypisać sumę wszystkich wartości w formacie:
Sum: [value] - Wypisać łączną liczbę przydzielonych bajtów w formacie:
Bytes allocated: [value]
Pamiętaj, aby dołączyć nagłówek <stdlib.h>, by móc używać malloc(). Twój program musi pokazać, jak ważne jest sprawdzenie, czy alokacja się nie powiodła, zanim podejmie się próbę użycia przydzielonej pamięci.
Na przykład, jeśli dane wejściowe to:
4
10 20 30 40Oczekiwane dane wyjściowe:
Memory allocation successful!
Sum: 100
Bytes allocated: 16To wyzwanie podkreśla, jak ważne jest defensywne programowanie podczas pracy z dynamiczną alokacją pamięci. Dzięki niemu Twoje programy będą prawidłowo obsługiwać potencjalne błędy alokacji pamięci zamiast nieoczekiwanie ulegać awarii.
Spróbuj swoich sił
#include <stdio.h>
#include <stdlib.h>
int main() {
// Wczytaj liczbę liczb całkowitych
int n;
scanf("%d", &n);
// TODO: Napisz tutaj swój kod
// - Użyj malloc(), aby przydzielić pamięć na n liczb całkowitych
// - Sprawdź, czy przydzielenie pamięci się powiodło
// - Obsłuż zarówno przypadek powodzenia, jak i niepowodzenia
// - Wczytaj liczby całkowite i je zapisz
// - Oblicz sumę i liczbę przydzielonych bajtów
return 0;
}Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i sterowanie przepływem
1Podstawy wskaźników
Czym jest wskaźnik?Deklarowanie wskaźnikówOperator pobrania adresu (&)Operator dereferencji (*)Wskaźniki NULLPodsumowanie: podstawy wskaźników4Projekt: Proste narzędzie tekstowe
Przegląd projektuLiczenie znaków2Wskaźniki i tablice
Nazwy tablic jako wskaźnikiElementy tablic — wskaźnikiArytmetyka wskaźnikówPorównywanie wskaźnikówPodsumowanie: przechodzenie po tablicy za pomocą wskaźników5Wskaźniki i funkcje
Przekazywanie przez wartośćPrzekazywanie wskaźników do funkcjiModyfikowanie zmiennych za pomocą wskaźnikówKlasyczny przykład: zamianaPrzekazywanie tablic do funkcjiPowtórka: argumenty wskaźnikowe funkcji8Struktury i wskaźniki
Wskaźniki do strukturOperator strzałki (->)Przekazywanie struktur przez wartośćPrzekazywanie wskaźników do strukturDynamiczna alokacja strukturPodsumowanie: modyfikowanie struktury — wskaźnik11Końcowe zadania powtórkowe
Powtórka: dynamiczne łączenie ciągów znakówPowtórka: tablica strukturPowtórka: licznik częstotliwości słów3Tablice znaków i ciągi znaków
Ciągi znaków jako tablice charZnak końca ciąguWczytywanie ciągu za pomocą scanfUżywanie strlen()Używanie strcpy()Używanie strcat()Używanie strcmp()Podsumowanie: podstawowe funkcje do obsługi ciągów znaków6Zarządzanie pamięcią
Pamięć stosu a stertyAlokacja dynamiczna — malloc()Użycie sizeof() do alokacjiSprawdzanie niepowodzenia alokacjiZwalnianie pamięci za pomocą free()Alokacja za pomocą calloc()Podsumowanie: tablica dynamicznaPoćwicz samodzielnie: Kompilator C online