Autor
|
Tema: asignacion de array dinamico usando una variable no inicializada.. (Leído 3,510 veces)
|
digimikeh
Desconectado
Mensajes: 191
|
Hola amigos. que tal. Tengo el siguiente caso: #include <iostream> #include <initializer_list> struct x { private: int * iArray = nullptr; int tam; //Sin inicializar public: x(std::initializer_list<int> lst) : iArray{new int[lst.size()}, tam{lst.size()}{ std::copy(lst.begin(), lst.end(), iArray); } //Constructor de copia x(const x & otherX); }; //Definición de constructor de copia (notar aquí que al momento de hacer //la primera inicialización tam no ha recibido valor. x::x(const x & otherX) : iArray{new int[tam]}, tam{otherX.tam}{ for (int y = 0; y < tam; ++y){ iArray[y] = otherX.iArray[y]; } } int main (){ x x0 {2, 4, 6}; x x1 = x0; //copia correcta... //prueba directa de asignacion de una variable no definida a un array dinamico: int x; int * arr = new int[x]; //error, x no está definida. }
Como se puede observar, en la linea 22 se está inicializando el array dinamico con un tamaño de tam antes que inicializar al mismo tam, o sea, se esta inicializando con un valor desconocido... sin embargo, esta funcionando bien, ahora bien, en la linea 35, se esta intentando crear un array dinamico con un tamaño x, pero no sirvio.... acaso la inicialización funciona distinto a la asignacion? Gracias, saludos.
|
|
« Última modificación: 6 Julio 2019, 19:41 pm por digimikeh »
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
En C++ las cosas no necesariamente se ejecutan de izquierda a derecha sino que es el compilador quien decide el mejor orden para hacer las cosas. Busca sobre los sequence points. Por ejemplo: https://en.wikipedia.org/wiki/Sequence_point
|
|
|
En línea
|
|
|
|
digimikeh
Desconectado
Mensajes: 191
|
ok, el compilador determina esto siempre y cuando se este evaluando la línea actual o no?
Edit: Ya me quedo claro gracias.!
|
|
« Última modificación: 6 Julio 2019, 20:56 pm por digimikeh »
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
RayR
Desconectado
Mensajes: 243
|
No hay ninguna diferencia entre lo que haces en la línea 22 y la línea 35, desde el punto de vista de la no inicialización. De entrada, usar el valor de una variable no inicializada es totalmente incorrecto (por más que no sea un error de compilación), aunque supongo que lo sabes y este ejercicio es sólo un test para ver qué pasa. Ahora, el hecho de que aparentemente funcione bien en una línea pero no en la otra no tiene nada de extraño. Una variable no inicializada (a menos que sea variable global o static, que siempre son inicializadas a 0) tendrá "basura", es decir, cualquier valor que hubiera en la posición de memoria ocupada por esa variable. Si la línea 22 te funciona bien, simplemente significa que dio la casualidad de que el valor aleatorio que contenía tam era positivo y no muy grande. Si en la línea 35 tienes error, es porque la variable x (y por cierto, nunca deberías usar un mismo identificador para un tipo y para una variable) contenía un valor negativo o demasiado grande: new falla y arroja una excepción si se le pide reservar un número negativo de bytes o una cantidad mayor a la máxima que es posible reservar. Esto último depende de la implementación, la arquitectura para la que estés compilando, la cantidad de memoria disponible en el sistema, etc. Dado que no se puede predecir el valor de variables no inicializadas (es perfectamente posible que en otra PC, o con otro compilador, o con otra versión del mismo compilador, la línea 22 falle pero la 35 no, o que ambas fallen, o ninguna) siempre se deben inicializar antes de usarse.
|
|
|
En línea
|
|
|
|
Loretz
Desconectado
Mensajes: 117
|
Un momento... El orden en que se inicializarán los miembros de la struct x es en el orden en que se encuentren declarados en la struct; en este caso, primero iArray y después tam, y no importa en qué orden se escriban en la 'initializer list' del constructor. Hay un problema aquí donde dices: x x1 = x0; //copia correcta... Al invocar el copy constructor se va a ejecutar la inicialización de iArray antes que tam, de modo que la expresión al pretender acceder a tam sin inicializar se incurrirá en "Undefined behavior" (o sea, cualquier cosa --normalmente mala-- puede suceder).
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
He hecho unas pruebas y Rayr está en lo cierto. Se genera un array de tamaño aleatorio en el heap.
A la hora de copiar tam pero generar el array dentro del cuerpo del constructor.
|
|
|
En línea
|
|
|
|
digimikeh
Desconectado
Mensajes: 191
|
Entonces en tal caso no sería mejor inicializar tam y luego iArray con tam? o colocar primero en el campo privado del struct a tam y en la siguiente línea al array...
|
|
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Y si usas algo así: x::x(const x & otherX) : iArray{new int[otherX.tam]}, tam{otherX.tam}{ for (int y = 0; y < tam; ++y){ iArray[y] = otherX.iArray[y]; } } Ya que otherX.tam te sirve para copiar el tam también lo puedes usar para generar el array. O x::x(const x & otherX) : tam{otherX.tam}{ iArray = new int[tam]; for (int y = 0; y < tam; ++y){ iArray[y] = otherX.iArray[y]; } } Aunque, bueno, hablo desde el desconocimiento.
|
|
|
En línea
|
|
|
|
digimikeh
Desconectado
Mensajes: 191
|
Entiendo!.. gracias por contestar! He estado observando en el libro que estoy estudiando otras cosas que no me parecen (yo a pesar de ser un poco novato) muy comprensibles... Luego me puse a indagar sobre las Erratas del libro y me tope con esto: http://www.stroustrup.com/4th_printing3.htmlComo verán en la pagina 74 (que es justo el punto que quería discutir en este post), en realidad el problema es por una cuestion de impresion, es decir, lo que esta escrito en la pagina 74 fue sin intencion (por algun minuto se me paso que podia ser asi y que se habia cometido un error).. Dice: pg 74, top: s/new double[sz]/new double[a.sz]/ ...por lo que new double[a.sz] tiene mucho mas sentido que lo anterior... Saludos!
|
|
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Array dinamico
Java
|
Shell Root
|
6
|
10,610
|
11 Junio 2011, 17:10 pm
por Valkyr
|
|
|
Obtener tamaño de array dinamico
Programación C/C++
|
erest0r
|
2
|
2,830
|
1 Octubre 2013, 02:22 am
por erest0r
|
|
|
Asignacion de resultado a variable
Scripting
|
navivan
|
3
|
3,000
|
6 Marzo 2014, 21:57 pm
por navivan
|
|
|
Extraña asignación en un array con -1
Programación C/C++
|
kutcher
|
8
|
2,704
|
28 Julio 2014, 21:41 pm
por kutcher
|
|
|
Problemas con asignación de valores en un array
Scripting
|
Neofito_2017
|
0
|
1,865
|
3 Abril 2017, 17:06 pm
por Neofito_2017
|
|