• Domingo 22 de Diciembre de 2024, 22:49

Autor Tema:  Violacion de segmento al sumar 2 listas.  (Leído 2535 veces)

Hammerstrike

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Violacion de segmento al sumar 2 listas.
« en: Lunes 15 de Septiembre de 2008, 07:57 »
0
Hola:
Estoy tratando de sumar 2 listas de numeros enteros usando punteros y asignacion dinamica de memoria. El punto es que tengo algunas dudas, sobre todo cuando intento calcular la suma por que me da violacion de segmento.

Aqui va el codigo

Código: Text
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4.  
  5. #define MAXCOL 30
  6.  
  7. /*Sumar 2 tablas de numeros*/
  8.  
  9. main(){
  10.     int nfilas,ncols;
  11.     /*Definiciones de punteros*/
  12.     int (*a)[MAXCOL], (*b)[MAXCOL], (*c)[MAXCOL];
  13.  
  14.     /*Prototipos de funcion*/
  15.     void leerentrada(int (*a)[MAXCOL],int nfilas, int ncols);
  16.     void calcularsuma(int (*a)[MAXCOL],int (*b)[MAXCOL],int (*c)[MAXCOL],int nfilas,int ncols);
  17.     void sacarsalida(int (*c)[MAXCOL],int nfilas,int ncols);
  18.  
  19.     /*Pedir los datos*/
  20.     printf("Cuantas filas? n");
  21.     scanf("%d",&nfilas);
  22.     printf("Cuantas columnas? ");
  23.     scanf("%d",&ncols);
  24.  
  25.     /*Reserva de memoria inicial*/
  26.     *a[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  27.     *b[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  28.     *c[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  29.  
  30.     /*Leer las tablas*/
  31.     printf("Primera tabla: n");
  32.     leerentrada(a,nfilas,ncols);
  33.     printf("Segunda tabla: n");
  34.     leerentrada(b,nfilas,ncols);
  35.  
  36.     /*Calcular la suma*/
  37.     calcularsuma(a,b,c,nfilas,ncols);
  38.    
  39.     /*Desplegar la salida*/
  40.     printf("La tabla resultante es:n ");
  41.     sacarsalida(c,nfilas,ncols);
  42.  
  43. }
  44.  
  45. void leerentrada(int (*a)[MAXCOL],int n, int m){
  46.     int i,j;
  47.     printf("%d %d",n,m);
  48.     for (i=0;i<n;++i){
  49.         printf("nIntroducir datos para la fila nº %2dn",i+1);
  50.         for (j=0;j<m;++j){
  51. //          printf("Ingrese el elemento nº (%d,%d) de la tabla:n",i,j);
  52.             scanf("%d",(*(a+i)+j));
  53.         }
  54.     }
  55.  
  56.     return;
  57. }
  58.  
  59.  
  60. void calcularsuma(int (*a)[MAXCOL],int (*b)[MAXCOL],int (*c)[MAXCOL],int n,int m){
  61.     int i,j;
  62.    
  63.     for (i=0;i<n;++i){
  64.         for (j=0;j<m;++j){
  65.             *(*(c+i)+j)= *(*(a+i)+j) + *(*(b+i)+j);
  66.         }
  67.     }  
  68.  
  69.     return;
  70. }
  71.  
  72. void sacarsalida(int (*c)[MAXCOL],int n,int m){
  73.     int i,j;
  74.    
  75.     for (i=0;i<n;++i){
  76.         for (j=0;j<m;++j){
  77.             printf("%4d",(*(*(c+i)+j)));
  78.  
  79.         }
  80.     }
  81.     return;
  82. }
  83.  

Estare haciendo algo mal??? Lei por ahi que es recurrente el asociar el error violacion de segmento a punteros descarriados pero en este caso no se...
Alguna idea???
Gracias de antemano
Se que me puedes ver. No me puedes oir. Pero lo que hiciste no tiene NOMBRE...
Terminaste por cerrar hasta la mas minima ventana que habia entre nosotros...

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #1 en: Lunes 15 de Septiembre de 2008, 09:38 »
0
Hola Hammerstrike

Código: C
  1.  
  2. *a[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  3. *b[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  4. *c[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  5.  
  6.  

Si vas a reservar toda la memoria de golpe, ¿por qué no declaras directamente vectores de enteros? Malloc() es para ir reservando memoria cuando la necesites. Si reservas todo de golpe, es lo mismo que hacer

Código: C
  1.  
  2. int a[MAXCOL], b[MAXCOL], c[MAXCOL];
  3.  
  4.  

Aparte, haciendo

Código: C
  1.  
  2. *a[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  3.  
  4.  

incurres en un par de errores:

1. a[30] está fuera del rango de tu array, que va de 0 a 29.
2. Sólo reservas memoria para el puntero a[30], dejando los otros 30 (a[0] hasta a[29]) sin inicializar, por lo que podrían tener cualquier valor.

Ambos errores te pueden dar un SIGSEGV. Un saludo.

Hammerstrike

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #2 en: Lunes 15 de Septiembre de 2008, 17:58 »
0
Es que segun un libro la cosa deberia ser asi:

Código: Text
  1. *a=(int *) malloc(nfilas * ncols * sizeof(int));
  2.  

Pero me dice que los tipos son incompatibles en la asignacion.
Como podria solucionar esto???
Alguna idea???
Muchisimas gracias de antemano.
Se que me puedes ver. No me puedes oir. Pero lo que hiciste no tiene NOMBRE...
Terminaste por cerrar hasta la mas minima ventana que habia entre nosotros...

Rombus

  • Miembro MUY activo
  • ***
  • Mensajes: 105
  • Nacionalidad: ar
    • Ver Perfil
    • http://myspace.com/punkrecycle
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #3 en: Lunes 15 de Septiembre de 2008, 21:17 »
0
hola Hammerstrike

fijate que lo que te dice moskito es que al hacer
Código: Text
  1.  
  2. *a[MAXCOL]=(int *) malloc(nfilas * ncols * sizeof(int));
  3.  

estas alocando la memoria en el ultimo elemento de a

debido a esto:

Código: Text
  1. *a[MAXCOL] = . . .
  2.  

y lo que dice tu libro esta bien

pero presta atencion que no es a[MAXCOL], sino a a secas

Código: Text
  1. *a=(int *) malloc(nfilas * ncols * sizeof(int));
  2.  


esa forma igual es para declarar un vector de la cantidad de posiciones que tenga tu matriz, pero es un solo vector.

yo preferiria alocar el primer vector que sea el ancho, y luego por cada posicion alocar el alto ;)


saludos

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #4 en: Martes 16 de Septiembre de 2008, 01:38 »
0
Para declarar una matriz de manera dinamica, debes utilizar un apuntador de apuntadores.

A continuacion te dejo un codigo que crea, asigna, muestra y libera una matriz dinamica, parte del codigo esta tomado del C FAQ (http://www.faqs.org/faqs/C-faq/faq/) Seccion 6.16

Código: C
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. // Para asignar una matriz de manera dinamcia, debes usar un apuntador de apuntador
  6. int **a = NULL;
  7. int nfilas = 2;
  8. int ncols = 2;
  9. int i, j;
  10.  
  11. int main (int argc, char* argv[])
  12. {
  13.     // Crear la matriz de m x n
  14.     // Primero las filas
  15.     a = (int **) malloc(nfilas * sizeof(int *));
  16.     // Luego las columnas
  17.     for (i = 0; i < nfilas; i++)
  18.     {
  19.         a[i] = (int *) malloc(ncols * sizeof(int));
  20.     }
  21.  
  22.     // Ahora si, la podemos usar como una matriz normal.
  23.     // Llenar la matriz con ceros
  24.     for (i = 0; i < nfilas; i++)
  25.     {
  26.         for (j = 0; j < ncols; j++)
  27.         {
  28.             a[i][j] = 0;
  29.         }
  30.     }
  31.  
  32.     // Imprimir la matriz
  33.     for (i = 0; i < nfilas; i++)
  34.     {
  35.         for (j = 0; j < ncols; j++)
  36.         {
  37.             printf("Elemento %d,%d = %dn", i+1, j+1, a[i][j]);
  38.         }
  39.     }
  40.    
  41.     // Liberar la memoria
  42.     for (i = 0; i < nfilas; i++)
  43.     {
  44.         free(a[i]);
  45.     }
  46.    
  47.     free(a);
  48.  
  49.     system("pause");
  50.  
  51.     return 0;
  52. }
  53.  
  54.  

Espero te sirva.

Sakudos :hola:

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

Hammerstrike

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #5 en: Martes 16 de Septiembre de 2008, 06:40 »
0
Hola a todos.
Muchas gracias por las respuestas.
Rombus: Al principio lo hice como decia en el libro tal cual como tu me indicas. Pero lamentablemente me da un error (estoy usando Gcc 4.1 en debian) me dice "Incompatible types in assignment". De todas maneras voy a chequear la parte de asignar memoria por posicion. Muchas gracias.

ProfessorX: Muchas gracias por el ejemplo. Te aseguro que me servira.

Suerte
Hammer
Se que me puedes ver. No me puedes oir. Pero lo que hiciste no tiene NOMBRE...
Terminaste por cerrar hasta la mas minima ventana que habia entre nosotros...

Hammerstrike

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #6 en: Martes 16 de Septiembre de 2008, 08:05 »
0
He logrado compilar bien el programa. Pero parece que este gcc es bastante mañoso por que me da errores incluso siguiendo la notacion del libro que tengo. Como les decia, tuve que hacer lo siguiente:

Código: Text
  1.  
  2.         /*Reserva de memoria inicial (filas)*/
  3.         a=(int *) malloc(nfilas * sizeof(int));
  4.         b=(int *) malloc(nfilas * sizeof(int));
  5.         c=(int *) malloc(nfilas * sizeof(int));
  6.     /*Ahora reserva para las columnas*/
  7.     for (i=0;i<ncols;++i){
  8.         *a[i]=(int *) malloc(ncols * sizeof(int));
  9.         *b[i]=(int *) malloc(ncols * sizeof(int));
  10.         *c[i]=(int *) malloc(ncols * sizeof(int));
  11.     }
  12.  
  13.  
El error esta cuando dejo la asignacion incial (filas) de esta manera:
Código: Text
  1.  
  2.         /*Reserva de memoria inicial (filas)*/
  3.         *a=(int *) malloc(nfilas * sizeof(int));
  4.         *b=(int *) malloc(nfilas * sizeof(int));
  5.         *c=(int *) malloc(nfilas * sizeof(int));
  6.  
  7.  

Me da el siguiente error y no tengo idea por que:

Código: Text
  1.  
  2. :27:error: incompatible types in assignment
  3. :27: error: incompatible types in assignment
  4. :28: error: incompatible types in assignment
  5.  
  6.  

Lo bueno es que lo logre hacer funciona
Muchas gracias por las respuestas.
Salu2
Hammer
Se que me puedes ver. No me puedes oir. Pero lo que hiciste no tiene NOMBRE...
Terminaste por cerrar hasta la mas minima ventana que habia entre nosotros...

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #7 en: Martes 16 de Septiembre de 2008, 08:34 »
0
Código: C
  1.  
  2. *a=(int *) malloc(nfilas * ncols * sizeof(int));
  3.  
  4.  

No es que gcc sea mañoso, es que esta sentencia está mal (a lo mejor un error tipográfico en el libro, o un error a secas, son comunes en los libros de programación), pues estás asignando un un puntero a entero (int *) a un entero (*a). Lo correcto, como has podido comprobar, es:

Código: C
  1.  
  2. a=(int *) malloc(nfilas * ncols * sizeof(int));
  3.  
  4.  

a (int *) se le asigna un valor (int *). Saludos-

Hammerstrike

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Re: Violacion de segmento al sumar 2 listas.
« Respuesta #8 en: Martes 16 de Septiembre de 2008, 18:10 »
0
Si, muchas gracias.
Se que me puedes ver. No me puedes oir. Pero lo que hiciste no tiene NOMBRE...
Terminaste por cerrar hasta la mas minima ventana que habia entre nosotros...