Problema en C puntero a punteros.

Iniciado por Sicherer, 8 Septiembre 2017, 03:31 AM

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

Sicherer

Buenas, como va?
Soy nuevo en el foro y tenia una duda sobre Punteros a punteros en C.

Tengo q hacer una struct matriz

typedef struct {
short filas,col;
int **matriz;
}Matriz;

Ahora, mi duda es la siguiente:
¿Es necesario reservar memoria? Si.
¿Como la reservo? (la idea del programa es que la matriz se dimensione por teclado y se autocomplete con srand()).
¿Las funciones a un puntero puntero, llevan * en el nombre?

Desde ya muchas gracias, y si podrian dar un ejemplo se agradece mucho! saludos y que sigan bien.

AlbertoBSD

Tienes que definir como vas a trabajar. un Puntero de punteros tiene que tener una doble inicializacion, primero para definir cuantos apuntadores vas a tener y posteriormente Cada uno de esos apuntadores recien.

Puedes trabajar con un solo apuntador para toda la matriz


int *matriz;

matriz = calloc(filas*columnas,sizeof(int));





Ejemplo completo con matriz de punteros y cada puntero a un arreglo de enteros.


#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define MAGIC 354093428

typedef struct {
short filas,col;
int **matriz;
}Matriz;

int main() {
short filas = 10; // Aqui puedes capturar filas
short col = 5; // Aqui puedes capturar filas
srand(time(NULL)+ MAGIC);
Matriz m;
m.filas = filas;
m.col = col;
m.matriz =  calloc(m.filas,sizeof(int*));
int i = 0,j;
while(i < m.filas) {
m.matriz[i] = calloc(m.col,sizeof(int));
printf("File %2i:\t",i+1);
j =0;

while(j < m.col) {
m.matriz[i][j] = rand() % 1000;
printf("[%3i]",m.matriz[i][j]);
j++;
}
printf("\n");
i++;
}
}
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

Sicherer

#2
Muchas gracias alberto! y una ultima pregunta (me marea como manejar los punteros cuando paso por referencia en una funcion)

en el caso que yo quiera generar la matriz a  travez de una matriz...

Matriz crearMatriz() {
  Matriz *m;
  printf("nº de filas?");
  scanf("%d",m->filas);
  printf("nº de cols?");
  scanf("%d",m->cols);
  m->matriz =  calloc(m.filas,sizeof(int*));
int i = 0,j;
while(i < m->filas) {
m->matriz[i] = calloc(m->col,sizeof(int));
printf("File %2i:\t",i+1);
j =0;

while(j < m->col) {
m->matriz[i][j] = rand() % 1000;
printf("[%3i]",m->matriz[i][j]);
j++;
}
printf("\n");
i++;
}
return m;
}



o tengo que declararle la cantidad de memoria que usa en el main?


· Los códigos deben ir en etiquetas GeSHi
>aquí las reglas del foro
-Engel Lex

AlbertoBSD

Puede quedar asi:

Matriz *crearMatriz();

int main() {
Matriz *nueva = crearMatriz();
}

Matriz *crearMatriz() {
   Matriz *m;
   m = calloc(1,sizeof(Matriz));
   printf("nº de filas?");
   scanf("%d",m->filas);
   printf("nº de cols?");
   scanf("%d",m->cols);
   m->matriz =  calloc(m.filas,sizeof(int*));
int i = 0,j;
while(i < m->filas) {
m->matriz[i] = calloc(m->col,sizeof(int));
printf("File %2i:\t",i+1);
j =0;

while(j < m->col) {
m->matriz[i][j] = rand() % 1000;
printf("[%3i]",m->matriz[i][j]);
j++;
}
printf("\n");
i++;
}
return m;
}


Si la funcion crear Matriz devuelve un apauntador, este debe de tener el *antes del nombre tal como lo puse.


Asi mismo la funcion debe de reservar memoria para la Estructura de la matriz que vas a usar.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

Tucho

Buenas, un par de detalles nomás sobre la respuesta de AlbertoBSD.

En las lineas 11 y 13, falta el & en los scanf.
Por otro lado, no veo por que utilizar calloc en lugar de malloc, es mas lento y de todos modos despues le asignas un valor a cada uno de los elemetos, asi que estaria de más inicializarlos en cero.

En la linea 14 es m->filas (dentro del calloc).

Es una buena practica además, castear lo que devuelve el malloc, si bien todo deberia funcionar igual, te devuelve un void* y lo estas igualando a un Matriz* por ejemplo en la linea 9. Te evitas que te joda el compilador. Otra practica muy recomendable (si no casi obligatoria) es corroborar que todo sale bien, si falla el primer calloc ya todo el resto te va a tirar segmentation fault por todos lados, un:

if(m==NULL){fprintf(stderr,"Error allocando, linea %d\n", __LINE__); exit(EXIT_FAILURE);}


te salva las papas (sobretodo en programas mas complejos.) O definir una funcion por ejemplo:

void *safe_malloc(int n, size_t size){
       void *aux;
       aux = calloc(n,size);
       if(aux==NULL){
             fprintf(stderr,"Error Allocando %d bytes", n*size);
             exit(EXIT_FAILURE);
       }
       return aux;
}


y despues simplemente en llamas a safe_malloc(cantidad,sizeof(tipo));

Un saludo,
Tucho.

AlbertoBSD

Buenas practicas y muy recomendables tus observaciones.

Sobre el codigo yo solo copie el código que puso Sicherer, en mi propuesta no use scanf, de hecho casi no recomiendo usar scanf.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

Sicherer

#6
matriz *crearMatriz() {
    matriz *m;
    int i=0,j;
    printf("Ingrese el num de filas.\n");
    scanf("%d",&m->filas);
    printf("Ingrese el num de filas.\n");
    scanf("%d",&m->col);
   
    m->matrix = (int**)malloc(sizeOf(int*));
    while(i<m->filas) {
        m->matrix[i] = (int*)malloc(sizeof(int));
        j = 0;
        while(j < m->col) {
            m->matrix[i][j] = (int*)malloc(sizeof(int));
            j++;
        }
       i++;
    }
}


intenté hacerlo con malloc, pero claramente no me salio, esto fue a lo que mas me acerqué..  :-\


AlbertoBSD

Es una combinación de fgets y strtol


int numero;
char *error = NULL;
char buff_numero[20];
fgets(buff_numero,18,stdin);
numero = (int) strtol(buff_numero,error,10);


Aun que otras formas como: fgets y sscanf

https://foro.elhacker.net/programacion_cc/fgets_para_enteros-t348368.0.html;msg1698285

Formas hay varias el problemas del scanf es que si le escribes una letra cunado capturas numeros el programa se cuelga y hace cosas raras.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW