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?

Foi útil?

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.

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