Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Cero++ en 10 Diciembre 2018, 15:06 pm



Título: Error lógico cuando compilo ejercicio - CONSULTA
Publicado por: Cero++ en 10 Diciembre 2018, 15:06 pm
Buenas a todos, les adjunto aquí el código que hice, tenía que re-dimensionar un puntero, tal que, al usar esa función mi puntero se modifique con su nuevo tamaño y siga manteniendo los valores antiguos más los nuevos.
Si me pueden explicar lo que estoy haciendo mal, sería de gran ayuda, así puedo entenderlo  ;D
Aquí el código:

Código
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <ctime>
  4. using namespace std;
  5. int *Redimensionar(int *p,int c_adicionales, int _tam_de_p);
  6. int main(int argc, char *argv[]) {
  7. srand(time(0));
  8. int *x=nullptr,n;
  9. cout<<"ingrese el tamanio del arreglo"<<endl;
  10. cin>>n;
  11. x=new int [n];
  12. for(int i=0;i<n;i++) {
  13. x[i]=rand()%200;
  14. }
  15. for(int i=0;i<n;i++) {
  16. cout<<x[i]<<" ";
  17. }
  18. cout<<endl;
  19. for(int i=0;i<n+2;i++) {
  20. delete []x;
  21. }
  22. int ceros;
  23. cout<<"Ingrese la nueva cantidad: "; cin>>ceros;
  24. x=Redimensionar(x,ceros,n); //Por que me da basura en los dos primeros valores?
  25. for(int i=0;i<n+ceros;i++) {
  26. cout<<x[i]<<" ";
  27. }
  28. return 0;
  29. }
  30.  
  31.  
  32. int *Redimensionar(int *p, int c_adicionales, int _tam_de_p){
  33. int *aux=nullptr; int _tam=_tam_de_p+c_adicionales;
  34. aux=new int [_tam];
  35. for(int i=0;i<_tam_de_p;i++) {
  36. aux[i]=p[i];
  37. }
  38. for(int i=_tam_de_p+1;i<_tam;i++) {
  39. aux[i]=0;
  40. }
  41. return aux;
  42. }


Título: Re: Error lógico cuando compilo ejercicio - CONSULTA
Publicado por: CalgaryCorpus en 10 Diciembre 2018, 15:15 pm
Elimina las lineas 19, 20 y 21.


Título: Re: Error lógico cuando compilo ejercicio - CONSULTA
Publicado por: Cero++ en 11 Diciembre 2018, 00:18 am
Buenas colega, me podrías explicar por qué funciona al hacer eso?
Gracias por responder!!!


Título: Re: Error lógico cuando compilo ejercicio - CONSULTA
Publicado por: K-YreX en 11 Diciembre 2018, 00:50 am
Línea 8: Declaras un puntero. Un puntero simplemente apunta, no es más.
Línea 11: Reservas memoria dinámica para n elementos del array. Ese espacio de memoria está apuntado por x. Cuando tienes memoria dinámica siempre tienes que tener un puntero apuntando ahí. Si el puntero apunta a otro sitio, pierdes esa memoria.
Línea 12-14: Guardas n valores aleatorios [0,199] en el array.

La función <Redimensionar()> coge el puntero que tenías reserva memoria adicional y añade 0 a ese espacio adicional. Antes de eso copias los valores de <x> (<p> en la función) en <aux> (el nuevo puntero) esto se hace en líneas 35-37. Si antes de llamar a la función borras la memoria de <x> cuando llegas a la función, <p> apunta a basura porque has borrado a lo que apuntaba originalmente.

Sin embargo aunque el programa ya funciona no estás liberando la memoria. Tienes que liberar la memoria en dos ocasiones:
- Primero, en la función. <x> apunta a un espacio de memoria pero después de llamar a la función va a apuntar a otro, va a apuntar al mismo sitio que <aux>. Entonces donde apuntaba <x> tienes que liberarlo antes de que acabe la función, pero después de que se ejecuten las líneas 35-37 para que no se copie basura.
- Segundo, al finalizar el programa. En la función has reservado memoria para <aux>. Luego has hecho que <x> apunte a ese espacio de memoria. Pero antes de que acabe el programa tienes que liberar el espacio a donde apunta <x>.

PD: Un array unidimensional se libera sin bucle <for>:
Código
  1. delete [] array;



Título: Re: Error lógico cuando compilo ejercicio - CONSULTA
Publicado por: CalgaryCorpus en 11 Diciembre 2018, 06:03 am
Buenas colega, me podrías explicar por qué funciona al hacer eso?
Gracias por responder!!!

Para mí resulta interesante saber por qué pusiste esas líneas ahí en primer lugar.


Título: Re: Error lógico cuando compilo ejercicio - CONSULTA
Publicado por: Cero++ en 11 Diciembre 2018, 20:42 pm
Para mí resulta interesante saber por qué pusiste esas líneas ahí en primer lugar.

Bueno, desde mi lógica fue así: puse el delete del puntero antes de la llamada de la función, porque pensaba que antes de hacer que apunte a un nuevo arreglo, que además, esta re-dimensionado, iba a dejar al puntero como si estuviese nulo y que así apuntara a la nueva dirección, ya que pensaba que mi puntero viejo, al tener un tamaño más pequeño no funcionaria, que solo tomaría la misma cantidad de valores y que por ende, al eliminarlo y hacer que apuntara a la nueva dirección re-dimensionada no habría inconvenientes. Por eso puse el delete antes de la invocación de la función.
Como veras, recién estoy aprendiendo esto, así que bueno, trato de razonar lo que estudio pero no siempre me resulta, pero con la ayuda de ustedes, que me dan la explicación de por qué cada cosa me termina de cerrar lo que estudié!  ;D


Título: Re: Error lógico cuando compilo ejercicio - CONSULTA
Publicado por: Cero++ en 11 Diciembre 2018, 20:51 pm

Sin embargo aunque el programa ya funciona no estás liberando la memoria. Tienes que liberar la memoria en dos ocasiones....
PD: Un array unidimensional se libera sin bucle <for>
Código
  1. delete [] array;


Colega, me ayudó un montón su explicación y ya con leer lo que puso Calgarys pude darme cuenta de dónde colocar los dos deletes incluso antes de que respondieras a mi consulta!!  ;D
Gracias!