excepção não processada quando dereferencing ponteiro de char no Visual C ++ 2008
-
12-09-2019 - |
Pergunta
Eu estou tentando fazer algum desenvolvimento C clássico no Visual C ++ 2008 que irá modificar os caracteres de uma string assim:
void ModifyString(char *input)
{
// Change first character to 'a'
*input = 'a';
}
Estou recebendo uma exceção não tratada quando tento mudar um personagem. Parece que eu poderia fazer isso no Visual Studio 6 ou usando gcc, mas talvez eu só estou esquecendo alguma coisa. O Visual Studio passar de alguma forma * caractere por valor (gerenciamento de memória). Se sim, como faço para desligar isso?
Solução
Você provavelmente passar um algum lugar literal string:
ModifyString("oops"); // ERROR!
C e C ++ permitem que você implicitamente convertido a partir de strings literais (que têm o tipo const char[]
) para char*
, mas tal uso é obsoleto. constantes string estão autorizados a ser alocado na memória só de leitura (e geralmente são), então se você tentar modificá-los, você vai ter uma violação de acesso (aka falha de segmentação ou erro de bus). Se o compilador não colocar as constantes string na memória só de leitura, o programa continuará a funcionar, mas é um comportamento indefinido.
A maneira correta de fazer isso é copiar a string em um buffer gravável:
// one way:
char mystring[] = "test";
ModifyString(mystring); // ok
// another way:
char mystring[64]; // make sure this is big enough!!
strcpy(mystring, "test");
ModifyString(mystring); // ok
Outras dicas
é a entrada de um literal de cadeia? Isso é provavelmente o problema. Caso contrário, você precisa postar mais código, como o ponteiro tem de alguma forma acabou apontando para um local somente leitura na memória.
É impossível responder a essa pergunta sem ver como ModifyString é chamado. A função em si é correta assumindo que é contrato é para ser passado um valor não-NULL.
No entanto, é possível para o site de chamada a falhar, fazendo uma série de coisas
- Passando NULL
- Passando char const por meio de um elenco mal
Eu não posso dizer exatamente por que isso não funciona, mas o problema está no seu código, não Visual Studio. Por alguma razão, você está passando um ponteiro inválido para a função. Ou é um ponteiro nulo, ou ele aponta para algum endereço que você não tem acesso de leitura a.
Se você postar um pouco mais do código (onde é a função chamada, e como é que se chama?), Que pode ser capaz de apontar o problema exato.
A razão que trabalhou em GCC ou VC6 é simplesmente que é um comportamento indefinido. O padrão C ++ não diz que "isso deve funcionar", ou "isso deve causar um acidente". Qualquer coisa pode acontecer se você escrever para a memória que você não tem acesso. E, dependendo do compilador e do sistema que você está executando o aplicativo em, o endereço você acaba acessando irá variar. Por pura sorte, você acertar um endereço que causou uma violação de acesso quando compilado com VC2008. Sob GCC e VC6, você não tiveram a mesma sorte, e tem código que apareceu ao trabalho , e simplesmente escreveu a algum endereço de lixo.