Gradul de optimizare a spatiului de memorie prin alocarea dinamica a memoriei in HEAP in C++

Alocarea de memorie la momentul executiei unei aplicatii permite utilizarea unui spatiu de memorie, exprimat in numar de bytes, cu exact dimensiunea de memorie heap necesara pentru stocarea datelor definite prin intermediul variabilelor. Alocarea la momentul compilarii permite rezervarea si utilizarea unui spatiu de memorie cu dimensiune predefinita, exprimata in numar de bytes. In aceasta situatie, dezvoltatorul software trebuie sa anticipeze spatiul de memorie de dimensiune maxima care poate fi utilizat in cadrul aplicatiei.

Astfel, de cele mai multe ori, la momentul executiei aplicatiei nu se utilizeaza intregul spatiu de memorie rezervat la momentul compilarii. Rezulta o utilizare ineficienta a resursei memorie prin neutilizarea intregului spatiu alocat. Un alt dezavantaj rezulta din nevoia utilizatorului de a utiliza date ce presupun rezervarea de zone de memorie mai mari decat cele definite la momentul compilarii.
Aplicatia de mai jos determina gradul de optimizare a spatiului de memorie rezultat din utilizarea memoriei heap in locul memoriei alocate la momentul compilarii. Indicatorul se determina ca raport intre numarul de bytes neutilizati in zona de memorie care ar fi fost alocata la momentul compilarii si numarul total de bytes rezervati pentru zona de memorie alocata la momentul compilarii. Datele stocate sunt siruri de caractere, vectori de char, iar zona de memorie alocata la momentul compilarii se determina ca produs intre numarul de siruri de caractere si maximul lungimii dintre aceste siruri. Sirurile de caractere si numarul acestora se introduc de la tastatura.

#include <string.h>
#include <stdio.h>
#include <iostream>

using namespace std;

void main()
{
    char **psir, sir[1000];
    int i, j, max = 0, dim, sumlg = 0, n;

    cout << "Numarul de siruri=";
    cin >> n;
    psir = new char *[n];
    for (i = 0; i < n; i++)
    {
        cout << "Introduceti sirul de caractere " << i + 1 << ":";
        fflush(stdin);
        gets(sir);
        dim = strlen(sir);
        sumlg += dim;
        if (max < dim)
            max = dim;
        psir[i] = new char[dim + 1];
        strcpy(psir[i], sir);
    }
    float gEc = ((max * n - sumlg) * 1.) / (max * n);
    cout << "Gradul de optimizare este: " << gEc << endl;

    for (i = 0; i < n; i++)
        delete[] psir[i];
    delete[] psir;
}

Semnificatiile variabilelor importante definite in cadrul aplicatiei:

  • psir: variabila pointer pentru gestionarea memoriei heap in care sunt stocate sirurile de caractere;
  • sir: variabila vector de char utilizata ca buffer pentru sirurile de caractere introduse de la tastatura;
  • n: numarul de siruri de caractere stocate in memoria heap;
  • max: dimensiunea, exprimata in numar de caractere, a sirului de lungime maxima;
  • dim: dimensiunea unui sir de caractere;
  • sumlg: suma dimensiunilor sirurilor de caractere, spatiul de memorie heap ocupat de sirurile de caractere;
  • gEc: indicatorul grad de optimizare a memoriei.

Daca se iau in considerare zonele de memorie heap ocupate de adresele de inceput a sirurilor de caractere si zona de memorie aferenta variabilei psir, atunci expresia indicatorului gEc in codul sursa C++ devine:

gEc = ((max * n - sumlg - n * sizeof(*psir) - sizeof(psir)) * 1.) / (max * n);

Daca numaratorul expresiei de mai sus este negativ, atunci nu se realizeaza economie de memorie.
Deoarece numaratorul este compus din expresii care au ca rezultat valori de tipul int, iar numitorul este de asemenea o expresie cu rezultat int, expresia numaratorului este inmultita cu valoarea elementului neutru in raport cu inmultirea pentru ca rezultatul raportului sa fie un numar real. In caz contrar, raportul genereaza un rezultat intreg, partea intreaga a numarului real.