Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Xenomorfo77 en 17 Octubre 2013, 00:22 am



Título: ¿Qué me falla?
Publicado por: Xenomorfo77 en 17 Octubre 2013, 00:22 am
Lo que quiero hacer es crear un array de 2 dimensiones para guardar varias notas por cada alumno.
Creo que la reserva de memoria está bien lo que me falla es al intentar cambiar un valor y nose porque.
He probado haciendo  m[j]=0;
Lo que quiero es hacer un scanf("%f",m[j]);


Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void reserva(float **w,int filas,int columnas) {
  5.     int i,j;
  6.     w = (float**) calloc(filas,sizeof(float *));
  7.     for(i=0;i<columnas;i++) {
  8.        w[i] = (float *) calloc(columnas,sizeof(float));
  9.        }
  10.  
  11. }
  12.  
  13.  
  14. int main()
  15. {
  16.    int numeroalumnos;
  17.    int numeronotas;
  18.    float **m;
  19.    int i,j;
  20.    printf("Cuantos alumnos?: ");
  21.    scanf("%d",&numeroalumnos);
  22.    printf("Cuantas notas por alumno?: ");
  23.    scanf("%d",&numeronotas);
  24.  
  25.    reserva(m,numeroalumnos,numeronotas);
  26.  
  27.    for(i=0;i<numeroalumnos;i++)
  28.    {
  29.        printf("Alumno %d\n",i+1);
  30.        for(j=0;j<numeronotas;j++) {
  31.            printf("\tNota %d: ",j+1);
  32.            m[i][j]=0; //Esto me falla
  33.        }
  34.        printf("\n");
  35.    }
  36.  
  37.  
  38.    return 0;
  39.  
  40. }
  41.  


Título: Re: ¿Qué me falla?
Publicado por: x64core en 17 Octubre 2013, 00:39 am
en "reserva" pasas una copia de la variable de tipo puntero a puntero asi que el puntero a la memroia reservada en el parametro es eliminada cuando se retorna la funcion, debes de pasar un puntero a puntero que apunta a otro puntero ( float***) pasando la direccion de la variable por supuesto o pasarla por referencia.

ademas reservar un array dinamico de esa manera no es lo mismo que declarar uno dinamico asi que esto:
Código:
m[i][j]=0;
esta incorrecto, esto es más usado en tiempo de diseño ya que el compilador resuelve el tamaño de la primera dimension, asi que debe ser:

Código:
(m[i])[j] = 0;


Título: Re: ¿Qué me falla?
Publicado por: Xenomorfo77 en 17 Octubre 2013, 00:46 am
en "reserva" pasas una copia de la variable de tipo puntero a puntero asi que el puntero a la memroia reservada en el parametro es eliminada cuando se retorna la funcion, debes de pasar un puntero a puntero que apunta a otro puntero ( float***) pasando la direccion de la variable por supuesto o pasarla por referencia.

ademas reservar un array dinamico de esa manera no es lo mismo que declarar uno dinamico asi que esto:
Código:
m[i][j]=0;
esta incorrecto, esto es más usado en tiempo de diseño ya que el compilador resuelve el tamaño de la primera dimension, asi que debe ser:

Código:
(m[i])[j] = 0;

thx por la respuesta pero como se pasa por argumento eso?
sería correcto esto?

float ***m2 = &m1;

reserva(m2,,,);



Título: Re: ¿Qué me falla?
Publicado por: x64core en 17 Octubre 2013, 00:48 am
thx por la respuesta pero como se pasa por argumento eso?


Se pasa la direccion de la variable usando & ( C ) o se declara el parametro como referencia siempre usando & (C++).


Título: Re: ¿Qué me falla?
Publicado por: Xenomorfo77 en 17 Octubre 2013, 00:50 am
Se pasa la direccion de la variable usando & ( C ) o se declara el parametro como referencia siempre usando & (C++).

Ok thx de nuevo, he probado y hace el primer loop bien pero en alumno2 el programa crashea


Título: Re: ¿Qué me falla?
Publicado por: x64core en 17 Octubre 2013, 00:53 am
Ok thx de nuevo, he probado y hace el primer loop bien pero en alumno2 el programa crashea

C++:
linea 4:
Código:
void reserva(float** &w,int filas,int columnas)

linea 32:
Código:
(m[i])[j]=0;

del src en el post #1


Título: Re: ¿Qué me falla?
Publicado por: rir3760 en 17 Octubre 2013, 03:06 am
he probado y hace el primer loop bien pero en alumno2 el programa crashea
Cuando actualices un programa por favor no respondas de esa forma ya que no hay manera de ayudarte a solventar el error, en su lugar publica el código fuente completo y actualizado. También indica el lenguaje de programación ya que C y C++ tienen diferencias como en este caso con el paso por referencia.

En la función tienes otro error:
Código
  1. w = (float**) calloc(filas,sizeof(float *));
  2. for(i=0;i<columnas;i++) {
  3.   w[i] = (float *) calloc(columnas,sizeof(float));
  4. }
Después de reservar el bloque principal debes reservar el bloque para cada fila utilizando como limite del bucle el numero de filas pero tu utilizas el numero de columnas.

----

Si el lenguaje es C ...

Para solucionar los problemas primero debes cambiar la función indicando que su primer argumento sera de tipo "float ***", dentro de la función aplicas indirección para acceder al objeto apuntado (la variable "m" de la función main):
Código
  1. void reserva(float ***w,int filas,int columnas)
  2. {
  3.   int i;
  4.  
  5.   *w = calloc(filas, sizeof **w);
  6.   for (i = 0; i < filas; i++)
  7.      (*w)[i] = calloc(columnas, sizeof *(*w)[i]);
  8. }

Y cuando llames a la función pasas como primer argumento la dirección de la variable "m" utilizando el operador "dirección de" (el '&'):
Código
  1. reserva(&m, numeroalumnos, numeronotas);

Un saludo