1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Problema em c++ Access Violation

Discussão em 'Programação' iniciada por merlin3000, 31 de Março de 2006. (Respostas: 5; Visualizações: 915)

  1. merlin3000

    merlin3000 Power Member

    Boas.. Estou a ter um problema com este código e não consigo dar com o erro.
    A funçao recebe uma string1 e devolve um apontador para string2 com a primeira e a ultima palavra de string1.

    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    using namespace std;

    char * nm_prul(char *nome)
    {
    char *temp = new char[sizeof(nome)];
    char *posi, *posf;
    strcpy(temp,nome);
    posi=strchr(temp,' ');
    posf=strrchr(temp,' ');
    if (posi && (posi!=posf))
    {
    *posi='\0';
    strcat(temp,posf);
    }
    return temp;
    }

    main()
    {
    char temp[]={"primeiro meio ultimo"};
    cout<<nm_prul(temp);
    system("PAUSE");
    }

    O programa pode correr bem como chegar a função e fazer exit (acontece normalmente no bloodshed dev). Se for feito um debug passo a passo funciona sempre bem até ao fim (tanto no dev como no vc++) mas no vc++ mesmo ao terminar o main dá "First-chance exception in teste.exe: 0xC0000005: Access Violation".

    Alguém me pode explicar porquê? Obrigado..

    Caso o programa não acuse erro nenhum tentem por mais uns quantos "cout<<nm_prul(temp);" a seguir ao primeiro.
     
  2. TuxBoss

    TuxBoss Power Member

    O primeiro erro que me parece é que ao fazeres char[sizeof(nome)] tás a atribuir só 4 bytes de memória total para o temp, o que, caso o nome tenha mais de 4 char's de tamanho, vai dar problemas com o strcpy (btw devias usar o strncpy() e o strncat() ).
    O Access Violation deve ser o equivalente ao SEGFAULT que está a acontecer por tentares aceder a posições de memória ilegais.
    Experimenta inicializar o temp como "new char[strlen(nome) * sizeof(char)]" a ver se o erro passa.
     
  3. merlin3000

    merlin3000 Power Member

    Ok, obrigado já vi onde estava o erro eu pensei que o sizeof() devolvesse o tamanho completo da string '\0' incluindo em:

    char temp[]={"primeiro meio ultimo"};
    cout<<sizeof(temp);
    podias-me dizer porque é que neste caso devolve e no outro caso devolve 4?

    De qualquer modo se sizeof() for substituido por strlen()+1 está resolvido é o tmanho que eu quero para criar o novo char.

    No exemplo que deste porque multiplicar o tamanho da string p"new char[strlen(nome) * sizeof(char)]" isso nao vai dar um tamanho cerca de 4 vezes maior do que o que eu quero?
     
  4. TuxBoss

    TuxBoss Power Member

    Vamos por partes. Em primeiro lugar char[] e char* são duas coisas diferentes. Em C se fizeres sizeof de um char[] ou de um char* vai-te dar a mesma coisa, 4 bytes (que é o tamanho de um pointer para um char), no C++ (pelo que li pq realmente tenho pouca experiencia a programar com esta linguagem) o sizeof de um char[] devolve o tamanho do array e o de um char* devolve os 4 bytes normais. Mas mesmo assim no caso do teu programa o argumento que tu estás a passar ao sizeof() é um char*, logo um pointer com tamanho de 4 bytes.

    Neste caso em particular podes utilizar só o strlen()+1, isto pq como estás a alocar memória para um conjunto de char's e como cada char ocupa 1 byte a situação funciona, no entanto é boa práctica utilizares sempre o strlen()+1 * sizeof(char), isto pq assim garantes que independentemente do tamanho definido para o tipo char na máquina em que estás a programar, o programa vai funcionar bem.
     
  5. merlin3000

    merlin3000 Power Member

    Entendido.. muito obrigado, andava aqui a volta com este problema, nunca me lembrei de verificar o sizeof() dentro da função.

    Novamente.. Obrigado
     
  6. badsatan

    badsatan Power Member

    Só uma pequena adenda: char a[] = "12345"; printf("%d\n", sizeof(a)); dá 6 (os cinco chars + \0) quer em C quer em C++. É que "a" representa de facto um array de memória com 6 posições. Mas se fizer char *b = a; o sizeof(b) já passa a ser 4 (em arq de 32bit) porque o "b" é um ponteiro para o inicio da zona de memória reservada por "a".
     

Partilhar esta Página