- A változókat inicializáljuk, mielőtt használatba vesszük. A nem inicializált változó használata nem várt működést eredményez.
int valami;
//memória szemetet ír ki, mivel nem inicializált válotozó
printf("%d", valami);
- Kerüljük a nem biztonságos függvények használatát, mint
gets(),strcpy(),strcat()éssprintf(). Ezen függvények nem ellenőrzik a buffer méretét és használatuk könnyen buffer overflow-t eredményezhet, ezért a biztonságos alternatíváikat használjuk:fgets(),strncpy(),strncat(),snprintf()
char buffer[11] = "Hello, "; // túl kicsi buffer
char secret[15] = "Ez egy titok"; // egy másik szöveg
char toAdd[6] = "World!";
strcat(buffer, toAdd); //buffer overflow
//biztonságos változat:
strncat(buffer, toAdd, sizeof(buffer) -1);
-
Ha a hívott függvényünknek van visszatérési értéke, ami a hívás sikerességét vagy sikertelenségét jelzi, akkor mindenképpen ellenőrizzük azt.
-
A
malloc()éscalloc()esetén minden esetben ellenőrizzük a visszatérési értéket. Ezen függvényekNULLértéket adnak vissza, ha nem sikerült a memória foglalás. -
Minden
malloc()híváshoz tartozzon egyfree()hívás. -
Egy pointer használata előtt mindig ellenőrizzük, hogy nem-e
NULLértékű -
Implementáljunk robosztus hibakezelést annak érdekében, hogy ha hiba történik a program végrehajtása közben, akkor ne okozzon adatvesztést.
-
Kerüljük a függő mutatókat. Ha egy pointert felszabadítottunk, akkor az értékét állítsuk
NULL-ra
int* list = (int*)malloc(15 * sizeof(int));
if (list == NULL)
{
printf("Memoria foglalasi hiba\r\n");
exit(1); //robosztus hibakezelés, mivel nem megyünk tovább
}
//műveletek a listával
free(list);
list = NULL; //függő mutató elkerülés
-
Pointer aritmetika esetén ügyeljünk arra, hogy az mindig az allokált memóriaterületben maradjunk.
-
Szövegekkel való műveletvégzéskor ügyeljünk arra, hogy a C függvénykönyvtár egyes függvényei automatikusan nem zárják le a szövegeket a
\0karakterrel. -
Aritmetikai műveleteknél ügyeljünk arra, hogy az értékek túlcsordulhatnak. A számítások eredményeit ellenőrizzük, hogy elfogadható határon belül vannak-e, mielőtt használjuk azokat.
int index = 2 + userInput;
if (index >= 0 && index < 15) {
//ellenőrizzük, hogy a tömb méretén belül vagyunk-e
printf("%d", list[index]);
}
- Kerüljük az implicit típuskonverziót. Ha adat típust szeretnénk váltani, akkor a szándékosságot jelezzük explicit konverzióval.
float c = 1.0f;
double d = 1.0e20;
if (c + d == d) {
//ez íródik ki, mivel implicit típus konverzió történik
printf("c + d == d\n");
} else {
//pedig ez lenne a helyes eredmény
printf(": c + d != d\n");
}
- Kerüljük az előjeles és előjel nélküli számok használatát egy kifejezésen belül, mivel az implicit típuskonverzióknak köszönhetően nem várt eredményt kaphatunk.
unsigned int x = 0xFFFFFFFF; //unsigned int maximum értéke
int y = 1;
if (x + y < x) {
//ez íródik ki, mivel x int-re konvertálódik, ami túlcsordul
printf("x + y < x\n");
} else {
printf("x + y >= x\n");
}
- Zárójelezéssel jelezzük egy összetett kifejezésben, hogy milyen sorrendben szeretnénk, hogy az kiértékelődjön.