Table of Contents

Read documentation

Bitdefender este un lider recunoscut în domeniul securității IT, care oferă soluții superioare de prevenție, detecție și răspuns la incidente de securitate cibernetică. Milioane de sisteme folosite de oameni, companii și instituții guvernamentale sunt protejate de soluțiile companiei, ceea ce face Bitdefender cel mai de încredere expert în combaterea amenințărilor informatice, în protejarea intimității și datelor și în consolidarea rezilienței la atacuri. Ca urmare a investițiilor susținute în cercetare și dezvoltare, laboratoarele Bitdefender descoperă 400 de noi amenințări informatice în fiecare minut și validează zilnic 30 de miliarde de interogări privind amenințările. Compania a inovat constant în domenii precum antimalware, Internetul Lucrurilor, analiză comportamentală și inteligență artificială, iar tehnologiile Bitdefender sunt licențiate către peste 150 dintre cele mai cunoscute branduri de securitate din lume. Fondată în 2001, compania Bitdefender are clienți în 170 de țări și birouri pe toate continentele. Mai multe detalii sunt disponibile pe www.bitdefender.ro.

Resposabili:

Cuprins

Scopul tutorialului

Limbajele de programare ne permit să-i transmitem unui calculator instrucțiuni pe care acesta să le înțeleagă și să le execute. Deși fiecare limbaj de programare are particularitățile lui, ele au în comun multe concepte similare, care, odată înțelese într-o manieră generică, pot fi aplicate în aproape orice limbaj de programare.

Exemple de astfel de concepte includ:

Pentru a înțelege cum se aplică astfel de concepte într-un limbaj de programare, trebuie să învățăm să căutăm și să aplicăm corect noțiunile prezentate în documentația acelui limbaj.

Ce reprezintă documentația unui limbaj

În programare, documentația este o colecție de texte, imagini, videoclipuri care au ca scop descrierea funcționalității unui software.

În particular, documentația unui limbaj de programare descrie funcționalitățile oferite de acel limbaj, sub forma unor reguli de sintaxă, dar și a unor biblioteci (standard sau non-stardard), framework-uri etc.

Documentațiile pot fi scrise atât de dezvoltatorii limbajelor, cât și de alte organizații, de aceea de multe ori găsim mai multe surse din care ne putem informa corect.

Ce este o bibliotecă? Dar un framework? Dar un API?

Notă: Acești termeni au multiple semnificații dependente de limbajul de programare, context etc. Nu vom da definiții exacte, ci vom oferi explicații sumare ca să vă faceți o idee despre diferența dintre aceste noțiuni.

Exemple de documentații

Cum integrăm o funcționalitate în codul nostru?

Vom parcurge niște pași orientativi și vom exemplifica fiecare pas pe o problemă dată.

Problemă propusă: Avem o listă de studenți, iar pentru fiecare student știm numele și grupa. Se cere o listă sortată a studenților după următoarele criterii: lexicografic după grupă, iar în caz de egalitate sortăm lexicografic după nume. Limbajul care trebuie folosit este limbajul C.

Comparație între o documentație și platformele de tip forum

Prin platforme de tip forum ne referim la: Stackoverflow, Quora, Ask Ubuntu, și alele.

Avantaje

Dezavantaje

În continuare vă vom oferi un exemplu de postare de pe Stackoverflow în care primul răspuns este unul greșit, deși este votat de mulți utilizatori: link.

În primul răspuns, este specificat că următoarele linii de cod sunt aproximativ același lucru din punct de vedere practic:

// varianta 1
artist = (char *) malloc(0);
 
// varianta 2
artist = NULL;

Cu toate acestea, dacă rulați următorul cod pe diverse platforme:

int *i = malloc(0);
*i = 100;
printf("%d\n", *i);

… surprinzător poate, dar pe anumite platforme veți obține rezultatul 100.

În schimb, dacă scrieți:

int *i = NULL;
*i = 100;
printf("%d\n", *i);

cel mai probabil veți primi Segmentation fault.

Așadar, practic vorbind, cele 2 coduri se comportă diferit. Deși primul cod pare că merge în anumite cazuri, în realitate el va ascunde un acces invalid la memorie pentru că se încearcă scrierea la o adresă de memorie nealocată. Să rulam cu valgrind acest program:

// bad_example.c
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    int *i = malloc(0);
    *i = 100;
    printf("%d", *i);
 
    return 0;
}
valgrind --leak-check=full ./bad_example
==51943== Memcheck, a memory error detector
==51943== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==51943== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==51943== Command: ./bad_example
==51943==
==51943== Invalid write of size 4
==51943==    at 0x109187: main (in /path/to/bad_example)
==51943==  Address 0x4a5a040 is 0 bytes after a block of size 0 alloc'd
==51943==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51943==    by 0x10917E: main (in /path/to/bad_example)
==51943==
==51943== Invalid read of size 4
==51943==    at 0x109191: main (in /path/to/bad_example)
==51943==  Address 0x4a5a040 is 0 bytes after a block of size 0 alloc'd
==51943==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51943==    by 0x10917E: main (in /path/to/bad_example)
==51943==
100==51943==
==51943== HEAP SUMMARY:
==51943==     in use at exit: 0 bytes in 1 blocks
==51943==   total heap usage: 2 allocs, 1 frees, 1,024 bytes allocated
==51943==
==51943== 0 bytes in 1 blocks are definitely lost in loss record 1 of 1
==51943==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==51943==    by 0x10917E: main (in /path/to/bad_example)
==51943==
==51943== LEAK SUMMARY:
==51943==    definitely lost: 0 bytes in 1 blocks
==51943==    indirectly lost: 0 bytes in 0 blocks
==51943==      possibly lost: 0 bytes in 0 blocks
==51943==    still reachable: 0 bytes in 0 blocks
==51943==         suppressed: 0 bytes in 0 blocks
==51943==
==51943== For lists of detected and suppressed errors, rerun with: -s
==51943== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

Observăm, așa cum ne-am aștepta, că avem un leak de memorie. Mai mult, accesăm locații de memorie pe care nu ar trebui, odată la atribuire, odată la afișare.

De ce uneori se afișează 100?

Răspunsul pe scurt este că malloc, în anumite situații, în spate alocă extra spațiu față de cât îi spunem noi. Dar acel spațiu nu este un spațiu pe care noi să-l putem folosi (nu ne garantează nimeni nici faptul că este alocat acel extra spațiu), iar accesul lui va conduce la comportament nedefinit, deoarece acolo pot fi stocate alte date. În anumite cazuri, se alocă acel spațiu extra unde se va stoca valoarea 100, iar mai apoi se va citi valoarea și se va afișa. Acesta este și motivul pentru care, în aparență, programul pare că merge. Mai multe detalii veți afla la cursul de SO.

Din nou, acest acces la memorie este incorect, nu faceți așa ceva deoarece aveți comportament nedefinit. Pentru a evita aceste situații vă recomandăm să utilizați tool-uri de memorie, cum ar fi valgrind.

Vă invităm să citiți toată conversația What’s the point of malloc(0)?, oferă niște puncte de vedere interesante despre acest subiect.

Concluzie: mare atenție când folosiți aceste platforme. Recomandarea noastră este să căutați în mai multe locuri răspunsuri și să testați orice cod folosiți din surse externe înainte de a-l integra în aplicațiile voastre.