¿Qué me falla?

Iniciado por Xenomorfo77, 17 Octubre 2013, 00:22 AM

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

Xenomorfo77

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 (cpp) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>

void reserva(float **w,int filas,int columnas) {
    int i,j;
    w = (float**) calloc(filas,sizeof(float *));
    for(i=0;i<columnas;i++) {
       w[i] = (float *) calloc(columnas,sizeof(float));
       }

}


int main()
{
   int numeroalumnos;
   int numeronotas;
   float **m;
   int i,j;
   printf("Cuantos alumnos?: ");
   scanf("%d",&numeroalumnos);
   printf("Cuantas notas por alumno?: ");
   scanf("%d",&numeronotas);

   reserva(m,numeroalumnos,numeronotas);

   for(i=0;i<numeroalumnos;i++)
   {
       printf("Alumno %d\n",i+1);
       for(j=0;j<numeronotas;j++) {
           printf("\tNota %d: ",j+1);
           m[i][j]=0; //Esto me falla
       }
       printf("\n");
   }


   return 0;

}

x64core

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:
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:

(m[i])[j] = 0;

Xenomorfo77

#2
Cita de: 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:
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:

(m[i])[j] = 0;

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

float ***m2 = &m1;

reserva(m2,,,);


x64core

Cita de: Xenomorfo77 en 17 Octubre 2013, 00:46 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++).

Xenomorfo77

Cita de: x64Core en 17 Octubre 2013, 00:48 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

x64core

#5
Cita de: Xenomorfo77 en 17 Octubre 2013, 00:50 AM
Ok thx de nuevo, he probado y hace el primer loop bien pero en alumno2 el programa crashea

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

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

del src en el post #1

rir3760

#6
Cita de: Xenomorfo77 en 17 Octubre 2013, 00:50 AMhe 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:
w = (float**) calloc(filas,sizeof(float *));
for(i=0;i<columnas;i++) {
  w[i] = (float *) calloc(columnas,sizeof(float));
}

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):
void reserva(float ***w,int filas,int columnas)
{
  int i;
 
  *w = calloc(filas, sizeof **w);
  for (i = 0; i < filas; i++)
     (*w)[i] = calloc(columnas, sizeof *(*w)[i]);
}


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 '&'):
reserva(&m, numeroalumnos, numeronotas);

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language