Más errores de Lvalue
Pregunta
A continuación se muestra un esquema de indexación triple anidada. Mi puntero a una variedad de punteros está desactivado en la línea comentada ... En teoría, esto debería darme un puntero. Resta uno de él y luego lo referro y lo reasigno a mi puntero a la matriz de punteros. Pero esa línea da un error de Lvalue para el operando "&".
Dejeme ser perfectamente claro. Quiero saber por qué el error está ocurriendo aquí y obtener un método que funcione para asignar la dirección del elemento anterior en la matriz de punteros a mi doble puntero de cuadro.
Solo aceptaré soluciones completas que satisfagan ambos criterios ...
#include <iostream>
typedef struct frame_s {
double ** TestArrayPointer;
} frame_t;
main () {
double * TestArray;
double ** TestPointerArray;
TestArray = new double [100];
TestPointerArray = new double * [100];
for (unsigned int Counter = 0; Counter<100; Counter++)
{
TestArray[Counter]=Counter;
TestPointerArray[Counter]=&(TestArray[Counter]);
}
frame_t Frames[10];
for (unsigned int Counter = 0; Counter<10; Counter++)
Frames[Counter].TestArrayPointer = &(TestPointerArray[Counter*10]);
//Move pointer to point at array position one back.
Frames[2].TestArrayPointer=
&(*(Frames[2].TestArrayPointer)-1); //error! here <--
//OUTPUT Values...
for (unsigned int Counter = 0; Counter<100; Counter++)
std::cout << "P: " << TestPointerArray[Counter] << " V: "
<< *(TestPointerArray[Counter]) << std::endl;
}
Solución
Frames[2].TestArrayPointer=
&(*(Frames[2].TestArrayPointer)-1);
Aquí, tanto la desferenciación como la recuperación de la dirección es innecesaria. Puedes hacer directamente -
Frames[2].TestArrayPointer = (Frames[2].TestArrayPointer)-1) ;
Pero esto tiene problemas potenciales.
- ¿Qué pasa si el índice es 0? Error de tiempo de ejecución.
- ¿Qué pasa si el índice es el último índice? Pérdida de memoria.
Otros consejos
Obtienes el error porque el -1
se aplica después del *
. No puede tomar la dirección del resultado del operador de sustracción; tal es un rValue, en lugar de un lvalor (Un LValue designa un objeto real: un rValue es solo un valor efímero).
Inicialmente, Frames[2].TestArrayPointer
puntos en el tercero double *
en la matriz señalada por TestPointerArray
. Presumiblemente, desea cambiarlo para señalar el segundo double *
en esa matriz en su lugar. Si es así, simplemente puede cambiar esa línea a:
Frames[2].TestArrayPointer = Frames[2].TestArrayPointer - 1;
Frames[2].TestArrayPointer
tiene tipo double**
*(Frames[2].TestArrayPointer)
tiene tipo double*
Asi que *(Frames[2].TestArrayPointer) - 1
es un temporal con tipo double*
. Un temporal es un rValue: no se puede tomar la dirección.
Creo que lo que quieres es:
&(*((Frames[2].TestArrayPointer)-1))
que también es un double*
, pero es el anterior a Frames[2].TestArrayPointer
en lugar de un temporal.
Y si nos deshacemos de los operadores de 'cancelar' y los parens redundantes:
Frames[2].TestArrayPointer - 1