Por que o wstring :: c_str causa um vazamento de memória se não for excluído corretamente

StackOverflow https://stackoverflow.com/questions/3424957

Pergunta

Segmento de código 1:

wchar_t *aString() 
{
     wchar_t *str = new wchar[5];
     wcscpy(str, "asdf\0");
     return str;
}
wchar_t *value1 = aString();

Segmento de código 2

wstring wstr = L"a value";
wchar_t *value = wstr.c_str();

Se o valor do segmento 2 do código não for excluído, não ocorre um vazamento de memória. No entanto, se o valor1 do segmento de código 1 não for excluído, há um vazamento de memória. O código interno para WString :: c_str parece o mesmo para mim.

Foi útil?

Solução

Uma regra importante: você deve usar delete em qualquer coisa que tenha sido criada por new, e você não deve excluir mais nada.

wstr.c_str() retorna um ponteiro para um buffer que é gerenciado pelo wstring objeto. Será desalocado quando a string for destruída, após o que o ponteiro não será mais válido. Usando delete sobre isso está errado. O ponteiro também será invalidado se você modificar a string.

aString() Retorna um ponteiro para um buffer que foi criado usando new[], então você deve excluí -lo quando terminar (usando delete[], para combinar new[]). Isso é propenso a erros, e é por isso que é melhor prática usar aulas de gerenciamento de recursos (como string, wstring, contêineres e ponteiros inteligentes) em vez de transmitir ponteiros crus e esperando que sejam tratados corretamente.

Outras dicas

Porque c_str() retorna um ponteiro para a representação interna do wstring. A classe mantém o controle dos dados que contém.

Tirado do basic_string::c_str() Documentação do MSDN:

A corda de estilo C retornada não deve ser modificado, pois isso poderia invalidar o ponteiro para a string, ou Excluído, pois a string tem uma vida útil limitada e pertence à sequência da classe.

Vou sair de um membro e dizer que um WString não é um wchar_t, mas uma classe que tem um operador para devolver um wchar_t *, então, no destruidor de WString, provavelmente libera sua própria cópia do wchar_t * ele retorna.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top