| Ver tema anterior :: Ver siguiente tema |
| Autor | Mensaje |
|---|
cigoba

Registrado: 27 Ago 2007 Mensajes: 39
| Publicado: 20/09/2007 4:16 pm | | | Título: Función calloc |
| Hola
Tengo entendido que no es necesario la conversión explícita o casting cuando se trabaja con las funciones malloc, calloc, y realloc.
Por ejemplo si tengo: p=(int*) malloc(n*sizeof(int*)), lo puedo reemplazar por p=malloc(n*sizeof*p);
Ahora si tengo: char *v; ... v=calloc(1, sizeof(char)); como sería la conversión sin casting?
Y con realloc si tengo: char *r; ... r = (char*)realloc( r, tamanyo/=2 ); Como sería sin el casting? Yo creo que es así: r=realloc(r, g*sizeof*r); Confirmen si es así.
Gracias de antemano _________________ esta es mi firma. |
|
| Volver arriba | |
 |
DCelso

Registrado: 28 Abr 2004 Mensajes: 112
| Publicado: 20/09/2007 5:23 pm | | | Título: |
| Todo mal, no se puede hacer nada de lo que cuentas. Venga, Saludos. |
|
| Volver arriba | |
 |
cigoba

Registrado: 27 Ago 2007 Mensajes: 39
| Publicado: 20/09/2007 5:33 pm | | | Título: |
| Haber arreglo el primero: int* p; ... p=(int*) malloc(n*sizeof(int*)), lo puedo reemplazar por: p=malloc(n*sizeof*p); ???
Y en mi última pregunta sería así: ... int g=5; char *r; ... r = (char*)realloc( r, tamanyo/=2 ); Como sería sin el casting? Yo creo que es así: r=realloc(r, g*sizeof*r); Confirmen si es así.
Gracias _________________ esta es mi firma. |
|
| Volver arriba | |
 |
|
DCelso

Registrado: 28 Abr 2004 Mensajes: 112
| Publicado: 20/09/2007 5:34 pm | | | Título: |
| La verdad es que lo que pones no tiene sentido. A ver si te encuentro algo que lo explique.
Ultima edición por DCelso el 20/09/2007 5:39 pm; editado 2 veces |
|
| Volver arriba | |
 |
cigoba

Registrado: 27 Ago 2007 Mensajes: 39
| Publicado: 20/09/2007 5:36 pm | | | Título: |
| mmm... _________________ esta es mi firma. |
|
| Volver arriba | |
 |
cigoba

Registrado: 27 Ago 2007 Mensajes: 39
| Publicado: 20/09/2007 5:45 pm | | | Título: |
| Vuelvo a empezar desde CERO con la pregunta. Arreglo todo-todo de nuevo porque me equivoqué con algunas cosas.
Tengo entendido que no es necesario la conversión explícita o casting cuando se trabaja con las funciones malloc, calloc, y realloc.
Por ejemplo si tengo: int *p; ... p=(int*) malloc(n*sizeof(int*)), lo puedo reemplazar por p=malloc(n*sizeof*p);
Ahora si tengo: char *v; ... v=calloc(1, sizeof(char)); como sería la conversión sin casting?
Y con realloc si tengo: char *r; int g=5; ... r = (char*)realloc( r, g); Como sería sin el casting? Yo creo que es así: r=realloc(r, g*sizeof*r);
 _________________ esta es mi firma. |
|
| Volver arriba | |
 |
|
DCelso

Registrado: 28 Abr 2004 Mensajes: 112
| |
| Volver arriba | |
 |
cigoba

Registrado: 27 Ago 2007 Mensajes: 39
| Publicado: 20/09/2007 6:15 pm | | | Título: |
| DCelso sé que en el primer punto donde hago el cambio esta bien (me refiero a malloc). Fijate en este post, en la tercer respuesta de un usuario aqui
Ahora mi pregunta es con las otras funciones calloc y realloc que puse anteriormente si se puede hacer lo mismo y de que forma.
S2  _________________ esta es mi firma. |
|
| Volver arriba | |
 |
cheroky
Registrado: 22 Sep 2005 Mensajes: 1372 Ubicación: En ecx esperando un call
| Publicado: 21/09/2007 1:09 am | | | Título: |
| | cigoba escribió: |
Ahora mi pregunta es con las otras funciones calloc y realloc que puse anteriormente si se puede hacer lo mismo y de que forma.
S2 :shock: |
Se puede omitir el cast o moldeado de tipo explicito sobre cualquier r-value derivado de una expresion de tipo puntero a void (void*) promocionandose al tipo destino.
Esto que probablemente te suene a chino en la practica se traduce como:
| Código: |
float *f = malloc(200 * sizeof *f) /* espacio para 200 elementos de tipo float*/ short *h = calloc(200,sizeof *h) /* idem para short */
/* */ h = realloc(h, 100); /* realocamos */
/* */ free(h); /* liberamos */
/* */
|
S2. _________________ - Explícito es mejor que implícito. - Simple es mejor que complejo. - Complejo es mejor que complicado. - Plano es mejor que anidado. - Ralo es mejor que denso. |
|
| Volver arriba | |
 |
|
mamntc02
Registrado: 30 Abr 2007 Mensajes: 242
| Publicado: 21/09/2007 1:17 am | | | Título: |
| Hola,
intentaré explicarlo con otras palabras, ya q quizá si tienes dos comentarios puedas entenderlo mejor. Supongo q tu pregunta es: Si usando malloc se puede o no obviar la conversión de tipo explicita, no? Es decir si hay q hacer casting. Primero hay q entender q quiere decir hacer casting. El compilador trata los datos en función del tipo de los mismos. Por tanto aunque haya un mismo dato en memoria (me refiero a los mismos 0s y 1s, y en la misma posición) el dato se representará de manera diferente en función del tipo. Por ejemplo, aunque tengas el valor 0x01ABCDEF en una zona de la memoria, éste será tratado diferente si el dato es un entero, un char[4] ó un campo de bits.
| Código: | unsingned int dato = 0x01ABCDEF; // Imagina q tienes este dato entero
unsigned char datoCh = *((char *)&dato);
printf("dato = 0x%X, datoCh = 0x%X\n", dato, datoCh);
| En este ejemplo he declarado un entero, y accedo al mismo dato ya sea como entero o como char. Si lo ejecutas te saldrá:| Cita: | | dato = 0x01ABCDEF, datoCh = EF | Quizá te esperases q datoCh fuese '01', pero esto es debido a q los procesadores basados en intel x86 son little-endian, lo q quiere decir q tratan la memoria "al revés" (desde el byte menos significativo al más significativo). Si trabajases con máquinas Solaris, Sparc o HP, q son big-endian entonces sí q te saldría '01' como datoCh. Pero esto tampoco te debe preocupar, ya q de esto se encarga el compilador y el SO.
Espero q hasta aquí esté más o menos claro.
El prototipo de la función malloc es:
| Cita: | | void *malloc( size_t size ); | El qual, devuelve un puntero a void. El puntero por supuesto será el mismo, ya q todos los punteros ocupan los mismo (4bytes en sistemas de 32bits), pero si no haces la conversión explícita del puntero, el dato al q apunta no sabe de q tipo es, por lo q no sabrá como tratarlo, aunque sepa de q tipo es el dato al q lo has asignado:
| Código: | char* data = NULL; data = malloc(4*sizeof(char));
|
Aunque data sea un puntero a char, al no hacer el casting le obligas al compilador a hacer una conversión implícita, con lo q se puede equivocar. Realmente no sé como se trata por defecto (si es q está estandarizado, cosa q dudo, por q dependería del compilador usado), pero no es una buena práctica obviar el casting, ya q lo más probable es q te dé resultados inesperados, como mínimo.
No sé si me he complicado mucho explicándolo.... espero q no 
Saludos |
|
| Volver arriba | |
 |
cheroky
Registrado: 22 Sep 2005 Mensajes: 1372 Ubicación: En ecx esperando un call
| Publicado: 21/09/2007 1:27 am | | | Título: |
| | mamntc02 escribió: | | Aunque data sea un puntero a char, al no hacer el casting le obligas al compilador a hacer una conversión implícita, con lo q se puede equivocar. Realmente no sé como se trata por defecto (si es q está estandarizado, cosa q dudo, por q dependería del compilador usado), pero no es una buena práctica obviar el casting, ya q lo más probable es q te dé resultados inesperados, como mínimo. |
En este contexto el cast en C estandar no es necesario, aunque hay una discusion algo intensa y extensa sobre del tema en el foro, por un servidor que lo recomienda.
El tipo promocionado se resuelve en la fase de diseño y no hay problemas de que el compilador se "equivoque".
S2. _________________ - Explícito es mejor que implícito. - Simple es mejor que complejo. - Complejo es mejor que complicado. - Plano es mejor que anidado. - Ralo es mejor que denso. |
|
| Volver arriba | |
 |
cigoba

Registrado: 27 Ago 2007 Mensajes: 39
| Publicado: 21/09/2007 7:44 am | | | Título: |
| Gracias amigos por sus valiosas respuestas. _________________ esta es mi firma. |
|
| Volver arriba | |
 |
|
rir3760

Registrado: 01 Oct 2004 Mensajes: 3657 Ubicación: Mexico
| Publicado: 21/09/2007 8:34 am | | | Título: |
| Para resumir:
* En el caso de C++ estandar este tiene un manejo mas estricto de los tipos (en relacion a C) y no es valido almacenar un puntero de tipo "void *" en una variable de tipo puntero (a otro tipo como "char *"), aqui la conversion explicita o casting es obligatoria.
* En el caso de C estandar este no requiere de la conversion ya que garantiza la conversion de un puntero a objeto (el que sea) a "void *" y "de regreso" con su valor intacto.
En este lenguaje el idioma (convencion informal dada por la practica) es omitir todas esas conversiones ya que son tan utiles (y necesarias) como el uso de la palabar reservada "auto". Tambien se prefiere el uso de "sizeof *p" en lugar de "sizeof(tipo)" ya que de esta forma la llamada a funcion no tiene que cambiarse si el tipo al cual apunta la variable "p" cambia.
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
|
| Volver arriba | |
 |
cigoba

Registrado: 27 Ago 2007 Mensajes: 39
| Publicado: 24/09/2007 10:26 am | | | Título: |
| Como estoy programando en C y no en C++, seguiré los consejos de cheroky y rir3760. Es decir reemplazaré en mis códigos
Esto: ... int *p; ... p=(int*) malloc(n*sizeof(int*)),
Por esto: ... int *p; ... p=malloc(n*sizeof*p);
Pero no desprecio para nada las otras respuestas. Gracias nuevamene  _________________ esta es mi firma. |
|
| Volver arriba | |
 |
|
|