it gets a void array
It can't possibly get a void array. It CAN get an empty array, but that is NOT the same as an array of type void.
Please do not post code full of commented out code. The commented out code is obviously NOT part of the problem. Delete it before posting code.
if (SIM808.available()) {
incoming_char = SIM808.read(); //Guardamos el carácter del GPRS
Serial.print(incoming_char); //Mostramos el carácter en el monitor serie
mensaje = mensaje + incoming_char ;
mensaje_sms();
Having read one character, why is it necessary to call mensaje_sms()?
char sms[] = "";
You've created an array that can hold 0 characters. How is THAT useful?
sprintf(aux_str, "AT+CMGS=\"XXXXXXXXXX\"", strlen(sms));
sms is NOT a string (because there is not room to hold even the NULL terminator, so you should not be passing it to a function that expects a string.
The do/while statement in enviarAT(), in which you have an if statement that makes sure that the do/while statement does nothing, is NOT appropriate. Use a while statement.
while(Serial.available()>0) Serial.read();
Why is it necessary to ensure that the incoming serial buffer is empty?
The do/while statement in reportar(), in which you have an if statement that makes sure that the do/while statement does nothing, is NOT appropriate. Use a while statement.
strtok(gpsdata, ",");
strcpy(latitud, strtok(NULL, ","));
strcpy(longitud , strtok(NULL, ","));
You must ALWAYS check that strtok() returned a valid pointer.
The lack of comments in your code make it very difficult to follow the complete flow, if you are not intimately familiar with all the AT commands.
Providing some serial output would be useful. It is difficult to tell that you ever actually sent the SMS to cause the GPS to be read. More Serial.print() statements in reportar() would be useful, too.