reservar memoria para punteros en C

Iniciado por Ghalad, 24 Mayo 2010, 18:28 PM

0 Miembros y 3 Visitantes están viendo este tema.

Ghalad

Hola a todos, tengo una duda sobre este tema. Entiendo que si declaro:

char *cadena;
cadena = (char*)malloc( (sizeof(char)*4) + 1);

estoy declarando un puntero a un string de 5 posiciones, pj: "HOLA"+'\0'.
Entonces tengo 2 preguntas:

1ro) que diferencia hay entre:
    (char*)malloc(sizeof(char)*5);
    (char*)malloc(sizeof(char*)*5);

2do) si lo que quiero es tener una lista de strings dinamica y declaro:

char **lista;

como declaro correctamente memoria para los distintos strings que quiera agregar a la lista? supongamos que los strings, en un determinado momento, son "hola1", "hola2", "hola3"

Eternal Idol

#1
Si, entendiste bien hasta ahi.

1)(char*)malloc(sizeof(char)*5);
Reserva memoria para 5 caracteres.

(char*)malloc(sizeof(char*)*5);
Reserva memoria para 5 PUNTEROS a caracteres (pero deberias hacer el casting a char **).

En realidad siempre reserva memoria simplemente, pero desde un punto de vista logico la diferencia seria esa con el casting correcto, en una PC con un S.O. de 32 bits, char = 1 byte, char *(y cualquier otro puntero) 4 bytes.

2) Reservas primero la memoria para los punteros a cadena y despues la memoria para las cadenas mismas.

Código (cpp) [Seleccionar]
//reservar
char **lista = (char**)malloc(sizeof(char*) * 3);
for (int x = 0; x < 3; x++)
{
 lista[x] = (char*)malloc(sizeof(char) * 5);
}
//usar
//liberar
for (int x = 0; x < 3; x++)
{
 free(lista[x]);
}
free(lista);
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Ghalad

ahhhh, bueno entonces dado mi programa...para generar la lista de strings seria correcto hacer:

void fnc(char** lista){
    lista = (char**)malloc( sizeof(char*)*5 );
    for(int i = 0; i < 5; i++){
        *lista = (char*)malloc( sizeof(char)*10);
        strcpy(*list, cadena); //cadena es un string que se genera dentro de la misma funcion, solo que no tengo ganas de poner la funcion completa porque interviene un base de datos, pero es un string.
        }
}


int main(){

char** lista, **ptr;

fnc(lista);

ptr = lista; //para no perder el puntero

while(*ptr != NULL)
{
    while(**ptr != '\0')
        printf("%s\n", *ptr++);
    ptr++;
}
}//fin del main

h0oke


Ghalad

#4
Código (cpp) [Seleccionar]
void fnc(char** lista){
   lista = (char**)malloc( sizeof(char*)*5 );
   for(int i = 0; i < 5; i++){
       *lista = (char*)malloc( sizeof(char)*10);
       strcpy(*list, cadena); //cadena es un string que se genera dentro de la misma funcion, solo que no tengo ganas de poner la funcion completa porque interviene un base de datos, pero es un string.
       }
}


int main(){

char** lista, **ptr;

fnc(lista);

ptr = lista; //para no perder el puntero

while(*ptr != NULL)
{
   while(**ptr != '\0')
       printf("%s\n", *ptr++);
   ptr++;
}
}//fin del main


asi? no tengo idea de como se usa
igual creo que camulle en los while para recorrer la lista

Eternal Idol

Esta mal la inicializacion ... siempre accedes a lista[0], mira el ejemplo que deje. El bucle esta mal del todo, primero y principal para poder usarlo tendrias que reservar un puntero mas y asignarle como valor 0; ademas de pasar la variable lista por referencia (la asignacion que haces ahora mismo en fnc es local, al volvera main lista sigue teniendo el mismo valor que antes de llamar a fnc).

Código (cpp) [Seleccionar]
while(*ptr != '\0')
        printf("%s\n", *ptr++);
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Ghalad

Si a la funcion le paso una referencia a lista, el prototipo no seria
void fnc(char*** lista); ????

entonces...
quedamos de acuerdo en que
Código (cpp) [Seleccionar]
char** lista;
lista = (char**)malloc( sizeof(char*)*5); // reservo espacio para 5 strings
lista = (char*)malloc( sizeof(char)*10); // reservo 10 bytes para 1 de los 5 strings


ahora, para copiar 1 cadena, es corecto?:
Código (cpp) [Seleccionar]
strcpy(lista[i], "mi cadena");

pensa que todo el tema de asignacion de memoria y strings se hace dentro de la funcion, no en el main.

Eternal Idol

Cita de: Ghalad en 24 Mayo 2010, 21:52 PMSi a la funcion le paso una referencia a lista, el prototipo no seria
void fnc(char*** lista); ????

Si, ahora mismo si inicializas lista a 0 y depuras vas a ver que lista sigue siendo 0.

Cita de: Ghalad en 24 Mayo 2010, 21:52 PMentonces...
quedamos de acuerdo en que
Código (cpp) [Seleccionar]
char** lista;
lista = (char**)malloc( sizeof(char*)*5); // reservo espacio para 5 strings
lista = (char*)malloc( sizeof(char)*10); // reservo 10 bytes para 1 de los 5 strings

Si.

Cita de: Ghalad en 24 Mayo 2010, 21:52 PMahora, para copiar 1 cadena, es corecto?:
Código (cpp) [Seleccionar]
strcpy(lista[i], "mi cadena");

Tambien.

Cita de: Ghalad en 24 Mayo 2010, 21:52 PMpensa que todo el tema de asignacion de memoria y strings se hace dentro de la funcion, no en el main.

Si, ya lo hice funcionar tanto en C (char*** como en C++ **&).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón


Ghalad

mm algo me funcionamal aver:

Código (cpp) [Seleccionar]

void obtenerLista(char ***lista)
{
     char buf[50];
     *lista = (char**)malloc(sizeof(char*)*5);
     for(int i=0; i<5; i++)
     {
             printf("Ingresa cadena: ");
             fgets(buf, 50, stdin);
             *lista[i]= (char*)malloc(sizeof(char)*strlen(buf));
             strcpy(*lista[i], buf);
     }
}


Código (cpp) [Seleccionar]

int main(){

    char **lista;
   
    obtenerLista(&lista);
   
    for(int i =0; i<5; i++){
        printf("grupo %d: %s", i, lista[i]);
    }
    for(int i=0; i<5; i++){
            free(lista[i]);
            }
    free(lista);
    retunr 0;
}


lo que quiero es una lista de strings, y como nose cuantos estoy le voy a poner a la lista estaria bueno, en vez de usar malloc(sizeof(char*)*5), usar realloc. Pero bueno si funciona con malloc despues se cambia.

que esta mal de ese codigo?