Problema em c++ Access Violation

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.
 
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.
 
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?
 
merlin3000 disse:
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?
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.

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?
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.
 
Entendido.. muito obrigado, andava aqui a volta com este problema, nunca me lembrei de verificar o sizeof() dentro da função.

Novamente.. Obrigado
 
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".
 
Back
Topo