Pergunta

Esta questão já tem uma resposta aqui:

  try {
        int* p = 0;
        *p = 1;
    } catch (...) {
        cout << "null pointer." << endl;
    }

Eu tentei capturar a exceção como este, mas ele não funciona, qualquer ajuda?

Foi útil?

Solução

Não há tal coisa como "exceção de ponteiro nulo" em C ++. As únicas exceções que você pode pegar, é as exceções explicitamente lançadas por expressões throw (plus, como Pavel observou, algumas exceções C ++ padrão jogados intrinsecamente por operator new standard, dynamic_cast etc). Não existem outras exceções em C ++. Dereferencing ponteiros nulos, divisão por zero etc. não gera exceções em C ++, que produz comportamento indefinido . Se você quiser exceções lançadas em casos como o que é de sua própria responsabilidade para detectar manualmente essas condições e fazer throw explicitamente. É assim que funciona em C ++.

O que quer que você parece estar à procura de se notar a ver com a linguagem C ++, mas sim uma característica especial a execução. No Visual C ++, por exemplo, o sistema / exceções de hardware pode ser "convertido" em exceções C ++, mas há um preço ligado a essa funcionalidade não-padrão, o que normalmente não é vale a pena pagar.

Outras dicas

Você não pode. De-referência a um nulo ponteiro é uma coisa do sistema.

No Linux, o sistema operacional gera sinais em sua aplicação. Dê uma olhada na csignal para ver como lidar com sinais. Para "pegar" um, você ligar uma função em que será chamado no caso de SIGSEGV. Aqui você pode tentar imprimir algumas informações antes de encerrar graciosamente o programa.

estruturada-manipulação de exceção . Você pode usar o __try/__except instristics, conforme descrito no link anterior. A maneira que eu fiz isso em um determinado utilitário de depuração que eu escrevi foi com a função _set_se_translator (porque se aproxima ganchos). Em Visual Studio, verifique se você tem SEH habilitado. Com essa função, você pode ligar em uma função a ser chamada quando o sistema gera uma exceção em sua aplicação; no seu caso seria chamá-lo com EXCEPTION_ACCESS_VIOLATION. Você pode, então, lançar uma exceção e tê-lo propagar voltar para fora como se uma exceção foi lançada em primeiro lugar.

Dereferencing um nula (ou ponteiro que é passado-a-extremidade da matriz, ou um apontador inválido aleatório) resulta em comportamento indefinido. Não há nenhuma maneira portátil para "pegar" isso.

Há uma maneira muito fácil de pegar qualquer tipo de exceção (divisão por zero, de violação de acesso, etc.) em Visual Studio usando try -> blocos catch (...).

ajustes Um projeto menor é suficiente. Basta ativar a opção /EHa em configurações do projeto. Veja Project Properties -> C / C ++ -> Geração de código -> Modificar o Habilitar excepções C ++ para "Sim com exceções SEH" . É isso aí!

Veja mais detalhes aqui: http://msdn.microsoft.com/ en-us / library / 1deeycx5 (v = vs.80) .aspx

não

C ++ não verificação de ponteiro (embora eu suponho que algumas implementações poderia). Se você tentar gravar em um ponteiro nulo é muito provavelmente vai bater duro. Não vai lançar uma exceção. Se você quiser pegar isso você precisa verificar o valor do ponteiro si mesmo antes de tentar escrever a ele.

Geralmente você não pode. Mesmo se você pudesse, seria como tentar colocar um band-aid em um submarino que tem um vazamento.

A aplicação aleijado pode fazer muito mais danos do que aquele que deixou de funcionar. Meu conselho aqui seria deixá-lo falhar, em seguida, corrigir por que ele caiu. Rinse. Repita.

Como já foi dito, você não pode fazer isso em C ++.

Se eu puder fazer um ponto mais amplo: mesmo em uma linguagem que permite que você pegá-lo, a ação é melhor para não tocar ponteiros nulos. Pegar um erro quando ele já está explodido em seu rosto, em seguida, tomar a decisão de seguir em frente como isso não aconteceu, não é uma boa estratégia de codificação. Coisas como dereference ponteiro nulo, estouro de pilha, etc, devem ser vistos como eventos catastróficos e defensivamente evitada, mesmo se o seu idioma permite-lhe reagir de forma diferente.

Não há nenhuma maneira independente de plataforma para fazer isso. Sob Windows / MSVC ++ você pode usar __try / __except

Mas eu não recomendo fazê-lo de qualquer maneira. Você quase certamente não pode recuperar corretamente a partir de uma falha de segmentação.

Se você quiser você pode apenas fazer o ponteiro verificando-se e jogue ...

if (p == nullptr) throw std::exception("woot! a nullptr!")
p->foo();

tão claro que isso seria apenas para depurar o problema, o nullptr não deve ocorrer em primeiro lugar:)

Curto Resposta-você pode não de uma forma portátil ou padrão, porque erros como este são potencialmente corromper o próprio processo.

Long Resposta-você pode fazer mais do que se poderia pensar, e definitivamente mais do que o padrão do programa apenas ondas quebrando. No entanto, você precisa manter 3 coisas em mente:
1) Estes erros são mais graves do que as exceções e muitas vezes não pode apresentar como exceções à sua lógica.
2) A sua detecção e tratamento de biblioteca deles será no back-end dependente de plataforma, mesmo que você pode fornecer uma interface abstrata limpa para consumo público.
3) Sempre haverá algumas falhas que são tão ruim que você não pode sequer detectá-los antes do fim.

Basicamente, falhas como segfaults ou corrupção de pilha não são exceções, porque eles estão corrompendo o processo real de executar o programa. Qualquer coisa que você codificado no programa é parte do programa, incluindo o tratamento de exceção, então qualquer coisa além de registrar uma mensagem de erro agradável antes de as matrizes processo é desaconselhável nos poucos casos, não é impossível. Em POSIX, o sistema operacional usa um sistema de sinalização de falhas de relatórios como estes, e você pode registrar funções de retorno de chamada para registrar o que o erro foi antes de você sair. No Windows, o sistema operacional pode, por vezes, convertê-los em exceções de aparência normal, que você pode pegar e se recuperar.

Em última análise, no entanto, a sua melhor aposta é a de código defensivamente contra esses pesadelos. Em um determinado OS haverá alguns que são tão ruim que você não pode detectá-los, mesmo em princípio, antes de seus dies processo. Por exemplo, corrompendo seu próprio stack pointer é algo que pode bater-lhe tão mal que até mesmo seus retornos de chamada de sinal POSIX nunca mais vê-lo.

No VC ++ 2013 (e versões anteriores também), você pode colocar pontos de interrupção em exceções:

  1. Pressione Ctrl + Alt + Delete (isto irá abrir o diálogo de exceção).
  2. Expanda 'Exceções Win32'
  3. Certifique-se de que "0xC0000005 violação de acesso" exceção está marcada.

Agora debug de novo, um ponto de interrupção será atingido exatamente quando o dereference o nulo aconteceu.

Não há exist exceção de ponteiro nulo em C ++, mas ainda você quer pegar o mesmo, então você precisa fornecer sua própria implementação da classe para o mesmo.

abaixo é o exemplo para o mesmo.

class Exception {

public:
   Exception(const string& msg,int val) : msg_(msg),e(val) {}
  ~Exception( ) {}

   string getMessage( ) const {return(msg_);}
   int what(){ return e;}
private:
   string msg_;
   int e;
};

Agora, com base no ponteiro NULL verificar pode ser jogou como, throw(Exception("NullPointerException",NULL)); e abaixo é o código para pegar o mesmo.

 catch(Exception& e) {
      cout << "Not a valid object: " << e.getMessage( )<< ": ";

        cout<<"value="<<e.what()<< endl;
   }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top