paulo1205
(usa Ubuntu)
Enviado em 26/09/2014 - 17:50h
Sobrescrever o valor de uma estrutura com bytes nulos só é aceitável quando seus campos internos são tipos nativos da linguagem (incluindo ponteiros) ou
arrays desses tipos nativos. Objetos de classes complexas, como
std::string , definitivamente inviabilizam essa prática comum do C.
Mesmo assim, e mesmo em C, é preciso ter cuidado quando a estrutura tem campos que são ponteiros, pois o simples fato de sobrescrever um ponteiro com um valor nulo não quer dizer que a memória para onde apontava antes será devidamente liberada.
O seu problema em particular é que o tipo
std::string tem vários campos internos que são usados para implementar a funcionalidade de um
string que se autoadministra, podendo mudar de tamanho dinamicamente (incluindo a alocação inicial e a desalocação final) e economizar memória através de compartilhamento de
bytes comuns com outros
strings que sejam copiados a partir dele. Quando você sobrescreve esses campos internos com valores arbitrários, interfere de modo completamente inesperado -- e negativo -- com a funcionalidade natural desses objetos.
Por qual motivo você está querendo sobrescrever seus
strings com bytes nulos? Impedir leitura de informação residual depois que ela não for mais necessária?
Se for esse último caso, você terá de fazer de outra maneira. Um jeito seria embutir um destrutor na sua classe (em C++, classes e estruturas são praticamente sinônimos, mudando apenas o tipo de acesso
default ao membros). Por exemplo:
struct Strings
{
std::string s1, s2;
u16 valores;
// Função de limpeza, para substituir o ‘memset(&objeto, 0, sizeof objeto)’.
// Você pode chamar essa função a qualquer momento.
void clear(){
valores=0;
s1.clear();
s2.clear();
/*
// Ou, se você quiser ser um pouco mais paranoico, o seguinte:
for(i=0; i<s1.length(); i++)
s1=0;
s1.clear();
for(i=0; i<s2.length(); i++)
s2[i]=0;
s2.clear();
*/
}
// Destrutor, invocado automaticamente quando o objeto deixa de existir.
~Strings(){
clear();
}
};
Alternativamente, você poderia estender o tipo [i]std::string, trazendo um pouco da limpeza paranoica para a própria gestão do
string .
class ParanoidString: public std::string {
public:
void clear(){
for(i=0; i<this->length(); i++)
(*this)=0;
std::string::clear();
}
~ParanoidString(){
clear();
}
};
struct Strings
{
ParanoidString s1, s2;
u16 valores;
// Função de limpeza, para substituir o ‘memset(&objeto, 0, sizeof objeto)’.
// Você pode chamar essa função a qualquer momento.
void clear(){
valores=0;
s1.clear();
s2.clear();
}
// Destrutor, invocado automaticamente quando o objeto deixa de existir.
~Strings(){
valores=0;
// Nem preciso limpar explicitamente s1 e s2: seus próprios destrutores farão isso.
}
};
Note, porém, que nenhum dos exemplos acima cobre a possibilidade de ter de limpar resíduos caso um dos campos [i]string seja modificado mais de uma vez ao longo da vida do objeto, principalmente se ocorrer redução de tamanho ou operação que envolva (re)cópia dos caracteres internos. Se você quiser algo do tipo, provavelmente terá de aumentar a quantidade de funções dentro de
ParanoidString , ou criar uma classe totalmente nova.