Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: agrichi en 15 Diciembre 2017, 18:19 pm



Título: Matriz dinámica
Publicado por: agrichi en 15 Diciembre 2017, 18:19 pm
Hola, Hice un programa que reserva memoria dinamicamente para una matriz, funciona bien hasta el final, ahí da error. Alguien sabe donde está el problema?
¿Está bien hecha la liberación de memoria al final del programa??
Gracias!!



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

int main()
{
int **punmem,i,j,k,filas,columnas;
printf("Ingrese la cantidad de filas: ");
scanf("%d",&filas);
punmem=(int **)malloc(filas*sizeof(int*));
if(punmem==NULL)
{
printf("Error al reservar memoria\n\n");
printf("Presione una tecla para salir\n\n");
getch();
exit(1);
}
for(i=0;i<filas;i++)
{
printf("\n\nCantidad de elementos de la fila %d: ",i+1);
scanf("%d",&columnas);
*(punmem+i)=(int *)malloc(columnas*sizeof(int));
if(*(punmem+i)==NULL)
{
printf("Error al reservar memoria\n\n");
printf("Presione una tecla para salir\n\n");
getch();
exit(1);
}
for(j=0;j<columnas;j++)   
{
printf("Elemento[%d][%d]: ",i+1,j+1);
scanf("%d",((*punmem)+i*columnas+j)); // Se puede poner &punmem[j]
}
printf("\nElementos de la fila %d:\n",i+1);
for(k=0;k<columnas;k++)
printf("%d ",(*((*punmem)+i*columnas+k)));
}
printf("\n\n\n");
for(i=0;i<filas;i++)
free(*(punmem+i));
for(i=0;i<filas;i++)
(*(punmem+i))=NULL;
free(punmem);
punmem=NULL;
return 0;
}


Título: Re: Matriz dinámica
Publicado por: CalgaryCorpus en 15 Diciembre 2017, 18:26 pm
Si dices cual es el error, ayudara' a ayudarte.

Tambien ayuda si encierras tu codigo usando el "Codigo GeSHI" que aparece cuando editas el mensaje. Usalo. El programa se vera mejor, tendra numeros de linea, etc.


Título: Re: Matriz dinámica
Publicado por: MAFUS en 16 Diciembre 2017, 13:17 pm
Te quitarías de problemas si en vez de usar aritmética de punteros lo hicieras con subíndices, como si se tratara de un array. Así solo te tendrías que preocupar del elemento y no de dónde está.

No tengo máquina para probar pero esta línea no me gusta
scanf("%d",((*punmem)+i*columnas+j));

Cuando un poco más arriba lo has hecho de esta forma
*(punmem+i)=(int *)malloc(columnas*sizeof(int));

Fíjate en los paréntesis.


Título: Re: Matriz dinámica
Publicado por: agrichi en 16 Diciembre 2017, 20:30 pm
Aquí pongo el programa con los números de línea
Cuando ejecuto el programa va todo bien pero al final me aparece un mensaje que dice que se escribió fuera de la zona de memoria del buffer "heap"
¿Donde está el error en el co´digo?
Gracias!!

Código
  1. // Programa que reserva memoria dinámicamente para una matriz de X filas, y para cada fila Y columnas
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <conio.h>
  6.  
  7. int main()
  8. {
  9. int **punmem,i,j,k,filas,columnas;
  10. printf("Ingrese la cantidad de filas: ");
  11. scanf("%d",&filas);
  12. punmem=(int **)malloc(filas*sizeof(int));
  13. if(punmem==NULL)
  14. {
  15.  printf("Error al reservar memoria\n\n");
  16.  printf("Presione una tecla para salir\n\n");
  17.  getch();
  18.  exit(1);
  19. }
  20. for(i=0;i<filas;i++)
  21. {
  22.  printf("\n\nCantidad de elementos de la fila %d: ",i+1);
  23.  scanf("%d",&columnas);
  24.  *(punmem+i)=(int *)malloc(columnas*sizeof(int));
  25.  if(*(punmem+i)==NULL)
  26.  {
  27.   printf("Error al reservar memoria\n\n");
  28.   printf("Presione una tecla para salir\n\n");
  29.   getch();
  30.   exit(1);
  31.  }  
  32.  for(j=0;j<columnas;j++)  
  33.  {
  34.   printf("Elemento[%d][%d]: ",i+1,j+1);
  35.   scanf("%d",((*punmem)+i*columnas+j));
  36.  }
  37.  printf("\nElementos de la fila %d:\n",i+1);
  38.  for(k=0;k<columnas;k++)
  39.   printf("%d ",(*((*punmem)+i*columnas+k)));
  40. }
  41. printf("\n\n\n");
  42. for(i=0;i<filas;i++)
  43.  free(*(punmem+i));
  44. for(i=0;i<filas;i++)
  45.  (*(punmem+i))=NULL;
  46. free(punmem);
  47. punmem=NULL;
  48. return 0;
  49. }
  50.  
  51.  
  52.  


Título: Re: Matriz dinámica
Publicado por: CalgaryCorpus en 16 Diciembre 2017, 21:27 pm
Cuando pides memoria, tienes 2 opciones:
- pides memoria para todos los enteros de una vez, considerando todas las filas y columnas, como si fuera un gran arreglo contiguo y luego haces la aritmetica tu mismo.
- pides memoria para distintas filas, cada fila es un arreglo unidimensional. Para este caso, pides memoria para direcciones de memoria por cada fila (como CASI lo haces en la linea 12, CASI porque pides memoria para enteros, no para direcciones de memoria) y luego pides memoria para todos los elementos en cada fila, como bien lo haces en la linea 24.

Como has decidido la 2da opcion (pedir memoria por filas):
1. Cambia la linea 12 para que diga sizeof(int *) en vez de sizeof(int)
2. Luego creo que podrias usar  
Código
  1. &punmem[i][j] (linea 35)
  o
Código
  1. punmen[i][k]  (linea 39)
, sin hacer la aritmetica explicita que haces.

La aritmetica que haces tiene solo sentido si en la linea 12 en vez de pedir memoria para 1 fila, pides memoria para todas las filas y columnas. No es el caso, veo que estas intentando acceder a memoria mas alla de lo que has solicitado.




Título: Re: Matriz dinámica
Publicado por: agrichi en 18 Diciembre 2017, 12:13 pm
Al fin lo conseguí
Este es el programa

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4.  
  5. int main()
  6. {
  7. int **punmem,i,j,k,filas,columnas;
  8. printf("Ingrese la cantidad de filas: ");
  9. scanf("%d",&filas);
  10. punmem=(int **)malloc(filas*sizeof(int *));
  11. if(punmem==NULL)
  12. {
  13.  printf("Error al reservar memoria\n\n");
  14.  printf("Presione una tecla para salir\n\n");
  15.  getch();
  16.  exit(1);
  17. }
  18. for(i=0;i<filas;i++)
  19. {
  20.  printf("\n\nCantidad de elementos de la fila %d: ",i+1);
  21.  scanf("%d",&columnas);
  22.  *(punmem+i)=(int *)malloc(columnas*sizeof(int));
  23.  if(*(punmem+i)==NULL)
  24.  {
  25.   printf("Error al reservar memoria\n\n");
  26.   printf("Presione una tecla para salir\n\n");
  27.   getch();
  28.   exit(1);
  29.  }  
  30.  for(j=0;j<columnas;j++)  
  31.  {
  32.   printf("Elemento[%d][%d]: ",i+1,j+1);
  33.   scanf("%d",((*(punmem+i))+j));         // LINEA MODIFICADA                
  34.  }
  35.  printf("\nElementos de la fila %d:\n",i+1);
  36.  for(k=0;k<columnas;k++)
  37.   printf("%d ",*(k+(*(punmem+i))));     // LINEA MODIFICADA
  38. }
  39. printf("\n\n\n");
  40. for(i=0;i<filas;i++)
  41.  free(*(punmem+i));
  42. for(i=0;i<filas;i++)
  43.  (*(punmem+i))=NULL;
  44. free(punmem);
  45. punmem=NULL;
  46. return 0;
  47. }
  48.  
  49.  
  50.  

He modificado dos líneas, la 33 y la 37, ahora funciona
Gracias a todos por los aportes!!


Título: Re: Matriz dinámica
Publicado por: CalgaryCorpus en 18 Diciembre 2017, 13:35 pm
Tambien modificaste la peticion de memoria en la linea 10.


Título: Re: Matriz dinámica
Publicado por: agrichi en 18 Diciembre 2017, 15:36 pm
Es verdad, me había olvidado!