Problema: Tamaño de Puntero char

Iniciado por yovaninu, 15 Agosto 2011, 22:55 PM

0 Miembros y 1 Visitante están viendo este tema.

yovaninu

Hola, tengo el siguiente codigo:
* Un puntero cad a char
* De tamaño 10

Luego de inicializarlo con strcpy, voy agregando cadenas con strcat, pero al ser la variable cad de 10 elementos, ¿no deberia haber un error?


Ademas mi idea es concatenar 'n' caracteres y no solamente '10', es decir no se sabe cuantas cadenas recibira la variable cad, ¿cual seria la declaracion?



Código (cpp) [Seleccionar]

#include <stdio.h>
#include <string.h>

int main()
{

char *cad;

cad=new char[10]();
strcpy(cad,"");

strcat(cad,"123");
strcat(cad,"456");
strcat(cad,"789");

strcat(cad,"abc"); //<-- Aqui deberia haber un error
strcat(cad,"def"); //<-- Aqui tambien pero el programa corre

        strcat(cad,"def"); //<-- Aqui el programa cierra abruptamente

printf("%s\n",cad);

return 0;

}


Saludos.

Queta

¿Programas en C o en C++? Si programases en C, el método de reserva de memoria no estaría bien dado que el operador new no existe en dicho lenguaje; una buena solución sería utilizar malloc (http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/). En el caso que programases en C++ el método de reserva de memoria tampoco sería válido ya que no utilizas este operador de forma correcta (http://www.cplusplus.com/doc/tutorial/dynamic/).

Como plus, mejor que no utilices ni strcpy ni strcat (http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html).
"Intenta no volverte un hombre de éxito, sino volverte un hombre de valor." Albert Einstein.

yovaninu

En C++, bajo VS 2005:

y este código???:

Código (cpp) [Seleccionar]

#include <stdio.h>
#include <string.h>

int main()
{

char *cad;

cad=new char[10];
strncpy(cad,"",1);

strncat(cad,"123",3);
strncat(cad,"456",3);
strncat(cad,"789",3);
strncat(cad,"789",3); // ???
strncat(cad,"789",3); // ???
strncat(cad,"789",3); //<-- Crash!!!


printf("%s\n",cad);

return 0;

}


Y sigo con la duda de como concatenar 'n' caracteres al primer parametro de strncat, ya que segun la definicion del codigo solo podria juntarle hasta 10 caracteres (claro que parece que recibe 15, luego se cierra el programa).



Gallu

Lo que sucede es que está machacando memoria que no le corresponde , al hacer el new [10] reservas memoria para un char de 10 , y solo le pertenecen 10 posiciones , pero como trabajas con punteros le puedes seguir asignando chars a la cadena , la función strncat no controla que cad pase del límite , lo único que controla es que el segundo argumento de dicha función tenga la longitud especificada en el tercer argumento , si es mayor no copia los caracteres restantes.
Ejecuta este y veras

#include <stdio.h>
#include <string.h>

int main()
{

char *cad[2];
char *cad2;

cad[0]=new char[10];
cad[1]=new char[10];
//strncpy(cad[0],"",1);

strncat(cad[0],"123",3);
strncat(cad[0],"456",3);
strncat(cad[0],"789",3);

strncat(cad[0],"789",3); // ???
strncat(cad[0],"789",3); // ???
strncat(cad[0],"789",3); //<-- Crash!!!


printf("%s %s\n",cad[0] , cad[1]);

return 0;

}
Nadie alcanza la meta con un solo intento, ni perfecciona la vida con una sola rectificación, ni alcanza altura con un solo vuelo.

yovaninu

Me cuesta entender a cerca de las cadenas dinamicas.

Por ejemplo en Basic declaramos esto

Dim Archivo as String

y 'Archivo' puede ser tan grande o pequeño como querramos.

En todo caso ¿cual es el equivalente en C++? para la variable archivo.

Mi idea inicial era tener una variable 'cad'

char *cad;

inicializarla con algo como esto:

cad=new char[];

y en 'cad' poder ir acumulando tantas frases o palabras como yo quisiera. por ejemplo

strcat(cad,"123");
strcat(cad,"456");
strcat(cad,"789");
strcat(cad,"abc");
strcat(cad,"def");
strcat(cad,"ghi");
strcat(cad,"jkl");
strcat(cad,"mno");
...

para luego de mostrar a 'cad'  con

printf("%d\n",cad);

me muestre por pantalla:

12345678abcdefghijklmno






.:BlackCoder:.

Supongo que te conviene leer sobre las variables del tipo "string", lee sobre esta clase antes de simplemente aprender a usarla... Tambien deberias leer sobre los "contenedores".

http://www.cplusplus.com/reference/string/string/

Saludos...

PD: Lee sobre memoria dinamica
"No te esfuerzes por saber mas, esfuerzate por ser el mejor en lo que sabes... Y asi sabras mas" .:BlackCoder:. jajaja




yovaninu

Estoy yá, leendo al respecto, hice algunas pruebas con algunos ejemplos y al parecer funciona. Sin embargo asumo que este nuevo tipo de dato es exclusivo de C++, y cual 'era' o 'es' la forma de hacerlo al puro estilo de C o Ansi C.

Gracias por todo.

Karman

Cita de: yovaninu en 15 Agosto 2011, 22:55 PMLuego de inicializarlo con strcpy, voy agregando cadenas con strcat, pero al ser la variable cad de 10 elementos, ¿no deberia haber un error?

te lo explico brevemente, cuando haces uso de malloc/new con valores pequeños la memoria reservada está en el heap (un espacio ya reservado para ser usado de esta forma), por lo que es posible que puedas desbordar el buffer hasta cierto límite (mientras lo que sobreescribas no afecte directamente a otro proceso/función, ya que si lo haces terminará provocando un error [los cuales son los más complicados de encontrar]), tb tienes que tener en cuenta que los tamaños son "redondeados" a tamaños prácticos para el CPU (en el caso del heap son alineados a sizeof(*void) [cuyo tamaño es distinto si es 32 o 64 bits] si mal no recuerdo) y en caso de espacios grandes de memoria a una página (512 bytes aprox), entonces si reservas 10 bytes, el redondeo será de 12 [en 32 bits] (3*sizeof(*void)=3*4=12)

S2

Gallu

Cita de: yovaninu en 16 Agosto 2011, 04:07 AM
y cual 'era' o 'es' la forma de hacerlo al puro estilo de C o Ansi C.
???

La respuesta es con realloc http://c.conclase.net/librerias/?ansifun=realloc

Aquí un ejemplo sencillo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CADENA 10

int main()
{

char *cad;
char *char_aux ;
int size_entrada = 0 , size_restante = 0;
int aux = 1;

//reservamos espacio para 10 char
cad = (char *) malloc(sizeof(char) * MAX_CADENA);
char_aux = (char *) malloc(sizeof(char) * MAX_CADENA);

do{
puts("ingresa una cadena(maximo 10 carácteres)");
fgets(char_aux , MAX_CADENA , stdin);
size_entrada = strlen(char_aux);
size_restante = MAX_CADENA - strlen(cad);

if(size_restante < size_entrada){
aux++;
cad = (char*) realloc(cad, MAX_CADENA * aux);
}
//pasamos del salto de linea
strncat(cad , char_aux ,size_entrada - 1);
}while (strcmp(char_aux, "\n") != 0 );

printf("%s \n",cad);

return 0;

}


Saludos.
Nadie alcanza la meta con un solo intento, ni perfecciona la vida con una sola rectificación, ni alcanza altura con un solo vuelo.