paulo1205
(usa Ubuntu)
Enviado em 09/12/2021 - 06:18h
ApprenticeX escreveu:
Bom dia a todos!
As facilidades de C++ são mais pesadas que C
char Text1[] = "Bom dia"; // 8 Bytes
std::string Text2("Bom dia"); // 32 Bytes
Cuidado para não comparar alhos com bugalhos. No exemplo acima,
Text1 tem em C++ exatamente a mesma representação que teria em C, consistindo numa região contígua de memória com 8 bytes de comprimento, onde são dispostos os sete caracteres do texto visível entre as aspas mais um byte nulo. Já
Text2 declara um objeto da classe
std::string, que possui sabe-se lá quantos campos internos e de quais tipos (embora se possa inferir que contém pelo menos um ponteiro, um medidor, do tipo
size_t, contendo o tamanho máximo reservado para a
string e um medidor, também do tipo
size_t, da quantidade de caracteres realmente ocupada).
Não fique muito tentado a usar
sizeof com objetos de classes como
std::string ou
std::vector, pois essas classes criam objetos que trabalham com alocação dinâmica, de modo que esses 32 bytes que você enxergou possivelmente nem sequer contêm o texto que você passou na inicialização através do construtor (dependendo da implementação, o objeto pode ter um
cache para textos curtos, mas num caso genérico, a memória ocupada pelo objeto e aquela ocupada pelos dados alocados dinamicamente podem ser completamente distintas).
struct {
char A[1], B[1];
} Database1[10]; // 20 Bytes
std::vector<std::vector<std::string>> Database2[10]; // 240 Bytes
De novo, a declaração de
Database1 produz exatamente o mesmo efeito em C++ que o que seria produzido em C. Já
Database2 usa um
array nativo com 10 elementos do tipo
std::vector<std::string>, e aqui também o comentário de que os 24
bytes de cada elemento (por isso um total de 240 bytes para todos os 10 elementos) significam apenas os campos que permitem representar um vetor (possivelmente um ponteiro para uma região de memória onde os elementos do vetor serão efetivamente dispostos, um medidor de capacidade máxima e outro do número de elementos em uso). Você pode manipular à vontade cada um desses dez elementos, colocando ou removendo
strings de diversos tamanhos em cada um deles, e
sizeof aplicado a
Database2 vai sempre retornar o mesmo valor.
O Problema começa qdo no exemplo acima eu preciso declarar os campos de char na Struct ANTES mesmo de usá-la! Ela fica gigante enquanto o vector do C++ só cresce conforme se usa!
Como posso montar uma Struct dinâmica que não fique pesada? Igual a um vector de vector de strings que não custa nada na memória até ser usado?
O que é “pesado”?
Arrays nativos têm realmente tamanho fixo e de pré-alocar toda a memória, mas eles costumam ser muito eficientes no acesso aos elementos. Por sua vez,
std::vector pode ter tamanho dinamicamente alterável, mas cada alteração de tamanho pode ser computacionalmente muito custosa (no pior caso, pode implicar a cópia de elementos preexistentes para novas regiões de memória a cada vez que o vetor muda de tamanho) mas, uma vez que você popule todo o vetor, geralmente o acesso a cada elemento deve ser praticamente tão eficiente quanto o seria usando um
array nativo.
Lembre-se de que não existe almoço grátis. Flexibilidade a mais costuma custar mais memória, mais tempo de CPU, ou ambos.
... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)