• Lunes 29 de Abril de 2024, 00:02

Autor Tema:  Error reservar memoria dentro funcion  (Leído 2401 veces)

krnl64

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
Error reservar memoria dentro funcion
« en: Miércoles 10 de Febrero de 2010, 22:17 »
0
Hola amigos.
Estoy intentando reservar memoria para una variable externa a la función que la reserva.
Dentro de la función la reserva y la usa,pero al volver el codigo a donde hizo la llamada
falla.
Concretamente falla en la linea 17 de main.c
Por más que miro no sé donde está el fallo.
Pueden hecharme una mano ?
Gracias.

aleatorio.h
Código: C
  1.  
  2. void alsr(int **vector, int inicio, int fin, int cuantos);
  3.  
  4.  

aleatorio.c
Código: C
  1.  
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include "aleatorio.h"
  5.  
  6. void alsr(int **vector, int inicio, int fin, int cuantos)
  7. {
  8.     int *temporal=NULL;
  9.     int i;
  10.     int j;
  11.     int pos;
  12.     int lon;
  13.  
  14.  
  15.     lon=fin-inicio; 
  16.  
  17.     /*Pedir memoria para temporal.*/
  18.     temporal=(int*)malloc(lon*sizeof(int));
  19.  
  20.     if(temporal==NULL)
  21.         return;
  22.  
  23.     for(i=0;i<lon;i++)
  24.     {
  25.         *(temporal+i)=inicio+i; 
  26.     }
  27.  
  28.     /*Pedir memoria array externo*/
  29.     *vector=(int*)malloc(cuantos*sizeof(int));
  30.     if(vector==NULL)
  31.         return;
  32.  
  33.     /*Llenamos el vector de aleatorios*/
  34.     for(i=0;i<cuantos;i++)
  35.     {
  36.    
  37.         /* Si tengo mas de un elemento */
  38.         if(cuantos > 1)
  39.         {
  40.             pos=rand()%lon;
  41.             /*Copio el elemento de esa posicion al original*/
  42.             *(vector+i)=*(temporal+pos);
  43.        
  44.             /*Realmente atrasamos el elemento del array*/
  45.             for(j=pos;j<lon-1;j++)
  46.                 *(temporal+j)=*(temporal+j+1);
  47.  
  48.             /*Vamos eliminando el ultimo elemento*/
  49.             lon--;     
  50.             temporal=(int*)realloc(temporal,lon*sizeof(int));
  51.         }
  52.         else
  53.         {      
  54.             *(vector+i)=*(temporal);
  55.         }
  56.  
  57.     }
  58.  
  59.  
  60.     free(temporal);
  61.     temporal=0;
  62.  
  63.     return;
  64. }
  65.  
  66.  

main.c
Código: C
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "aleatorio.h"
  5.  
  6. #define cantidad 2
  7.  
  8. int main(int argc,char *argv[])
  9. {
  10.     int *tmp=0;
  11.     int i;
  12.  
  13.     alsr(&tmp,1,5,cantidad);
  14.  
  15.     for(i=0;i<cantidad;i++)
  16.     {
  17.         printf(" %d ",*(tmp+i));
  18.     }
  19. }
  20.  
  21.  
  22.  

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Error reservar memoria dentro funcion
« Respuesta #1 en: Miércoles 10 de Febrero de 2010, 23:05 »
0
No mire mucho pero el compilador da dos warnings y esas lineas estan mal (C++ no compilaria esto  ^_^ ):
aleatorio.c(42) : warning C4047: '=' : 'int *' differs in levels of indirection from 'int'
aleatorio.c(54) : warning C4047: '=' : 'int *' differs in levels of indirection from 'int'


Lo depure rapidamente y tmp era un puntero hasta que llegue a la linea 42 y al ejecutarla se transformo en 2, al volver al main seguia teniendo ese valor.

PD. Esa manera se acceder a los arrays ya habras visto que no es la mas adecuada, cuesta leer el codigo y es facil equivocarse.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

krnl64

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
Re: Error reservar memoria dentro funcion
« Respuesta #2 en: Miércoles 10 de Febrero de 2010, 23:12 »
0
Cierto. No mire los warnings.

He sustituido el prototipo y el malloc por esto
Código: C
  1.  
  2. void alsr(int *vector, int inicio, int fin, int cuantos);
  3.  
  4.  

Linea 29 en aleatorio.c
Código: C
  1.  
  2. vector=(int*)malloc(cuantos*sizeof(int));
  3.  
  4.  

Entiendo que se queja de la indirección, pero ahora sigue fallando y no sé por qué ni cómo arreglarlo.
Ya no es un doble puntero.

Gracias

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Error reservar memoria dentro funcion
« Respuesta #3 en: Miércoles 10 de Febrero de 2010, 23:40 »
0
En el codigo original en vector TODO lo que tenes es 1 la direccion de memoria de tmp y 2, en *vector, su contenido (0). Lo que pasa es que estas accediendo a vector[0], es decir el *tmp, tal cual lo dice el warning. Estas haciendo vector[0] = numero que es lo mismo que *tmp = numero.

Esto si pone el numero donde debe ir:
Código: C
  1. (*(*(vector+i)))=*(temporal+pos);
  2. //legible:
  3. *vector[i] = temporal[pos];
  4.  

El problema es que no tenes mas lugar donde seguir poniendolos despues ... en cuanto i sea uno intentara acceder justo despues de la direccion de memoria de tmp como si fuera un puntero y boom.

Si no pasas la direccion de tmp (con **) esta seguira siendo 0 en main siempre y tal como estaba originalmente solo habia UN puntero.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

krnl64

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
Re: Error reservar memoria dentro funcion
« Respuesta #4 en: Miércoles 10 de Febrero de 2010, 23:48 »
0
Pude leer la explicación antes de que editaras.
Gracias Eternal.
Salu2

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Error reservar memoria dentro funcion
« Respuesta #5 en: Jueves 11 de Febrero de 2010, 00:08 »
0
El problema realmente esta al intentar acceder en alsr a los elementos como si fuera un array de punteros a int cuando no lo es.

Antes o despues de:
Código: Text
  1. int *temporal=NULL;
  2.  

Declaramos otro puntero comun tal como tmp:
Código: Text
  1. int *nvector = NULL;
  2.  

Despues de reservar memoria para vector hacemos:
Código: Text
  1. nvector = (int*)*vector;
  2.  

Accediendo finalmente de esta manera funcionara:
Código: Text
  1. nvector[i] = temporal[pos];
  2. ...
  3. //para el else
  4. nvector[i] = temporal[0];
  5.  
  6.  

PD. Usando nvector en lugar de vector podes usar tu sintaxis original pero no se entiende bien a simple vista  ;)

PD2. Cuidado con lon que puede volverse 0, con cantidad siendo 5 por ejemplo, y al calcular pos dar una excepcion por divir por 0.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

krnl64

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
Re: Error reservar memoria dentro funcion
« Respuesta #6 en: Jueves 11 de Febrero de 2010, 00:28 »
0
Cita de: "Eternal Idol"
El problema realmente esta al intentar acceder en alsr a los elementos como si fuera un array de punteros a int cuando no lo es.
Despues de reservar memoria para vector hacemos:
Código: Text
  1. nvector = (int*)*vector;
  2.  

Si, te entendi al ver
Código: C
  1.  
  2.  (*(*(vector+i)))=*(temporal+pos);
  3.  
  4.  
ya que en el contexto de la función es un doble puntero aunque realmente en su contexto original no lo era.
Me costo deducir el cast y luego lo he visto aqui escrito.

Hasta ahora solo habia reservado memoria para una variable externa a una función si usar esa memoria dentro de la función que la reserva.
Me acuesto habiendo aprendido algo más  :D

Gracias de nuevo.
Salu2

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Error reservar memoria dentro funcion
« Respuesta #7 en: Jueves 11 de Febrero de 2010, 00:33 »
0
De nadas  :comp:  B)  :beer:

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.