开发者

LValue Error When Trying to Reference Value in C

Here's one that's sure to be fun for someone. So I have an array of objects (in my test/demo code here, I just make them doubles for simplicity) and then I create an array of pointers to these objects.

The reason I do this is because I'm going to be swapping the objects, and swapping the objects themselves would be expensive, while swapping their pointers (in the secondary array) is cheap.

I have a number of subindexes inside my box data type. Basically, my goal is to be able to maintain contiguous stretches of pointers to objects that the box "owns". To do this, when I transfer from one box to another, I have to perform a number of swaps within the master pointer array. I do this via using the subindex inside my box structure, and it is there that the error occurs... see commented line for error.

#include <iostream>

typedef struct box_s {
  double * TestArrayPointer;
} box_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]);
  }
  for (unsigned int Counter = 0; Counter<100; Counter++)
    std::cout << "P: " << TestPointerArray[Counter] << " V: " 
          << *(TestPointerArray[Counter]) << std::endl;

  box_t Boxes[10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
    Boxes[Counter].TestArrayPointer = TestPointerArray[Counter*10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << Boxes[Counter].TestArrayPointer << " V: " 
          << *(Boxes[Counter].TestArrayPointer)
          << " P+1: " << (Boxes[Counter].TestArrayPointer)+1 << " V+1: " 
          << *((Boxes[Counter].TestArrayPointer)+1) 
          << " P: " << Boxes[Counter].TestArrayPointer <<std::endl;
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << &(Boxes[0].TestArrayPointer[Counter]) << " V: " 
          << Boxes[0].TestArrayPointer[Counter] << std::endl;


  unsigned int ExitBox = 1;
  unsigned int EntranceBox=9;
  unsigned int OldIndex = 12;
  double * TempPtr = TestPointerArray[OldIndex];

  if (ExitBox < EntranceBox)
  {
     //Swap final element of this box into old position
     TestPointerArray[OldIndex] = Boxes[ExitBox+1].TestArrayPointer-1;
     //Keep swapping start for end
     for(unsigned int BoxNum = ExitBox+1; BoxNum<EntranceBox &&
       BoxNum+1<=9;BoxNum++)
     {
        //Fill in new first with last element of old array.
        (Boxes[BoxNum-1].TestArrayPointer-1)=
      Boxes[BoxNum+1].TestArrayPointer-1; //darn l-value error!
    //Change array head pointer to match.
    Boxes[BoxNum].T开发者_StackOverflowestArrayPointer=Boxes[BoxNum-1].TestArrayPointer-1;
     }
     Boxes[EntranceBox].TestArrayPointer = TempPtr;
  }  
  for (unsigned int Counter = 0; Counter<100; Counter++)
     std::cout << "P: " << TestPointerArray[Counter] << " V: " 
           << *(TestPointerArray[Counter]) << std::endl;
}

I think it's because of the "-1", but I'm not sure why that's not valid, when I do similar things with "+1" in the loops above.

P.S. This is the REAL test code. I compile with

g++ main.cpp

. I didn't pay to careful attention to the comments and casing, just tried to stick with MSDN's suggested casing scheme, so don't judge... it's just a quick&dirty test!!

EDIT 1

Here is the working code for whoever cares... PMG I changed this to c++ given the new usage. And Heath I'm giving you credit, though your answer didn't solve the underlying problem.

Here is the real solution:

#include <iostream>

typedef struct box_s {
  double ** TestArrayPointer;
  unsigned int NumberPoints;
} box_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]);
  }
  for (unsigned int Counter = 0; Counter<100; Counter++)
    std::cout << "P: " << TestPointerArray[Counter] << " V: " 
          << *(TestPointerArray[Counter]) << std::endl;

  box_t Boxes[10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
  {
     Boxes[Counter].TestArrayPointer = TestPointerArray+Counter*10;
     Boxes[Counter].NumberPoints=10;
  }
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << Boxes[Counter].TestArrayPointer << " V: " 
          << *(Boxes[Counter].TestArrayPointer)
          << " P+1: " << (Boxes[Counter].TestArrayPointer)+1 << " V+1: " 
          << *((Boxes[Counter].TestArrayPointer)+1) 
          << " P: " << Boxes[Counter].TestArrayPointer <<std::endl;
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << &(Boxes[0].TestArrayPointer[Counter]) << " V: " 
          << Boxes[0].TestArrayPointer[Counter] << std::endl;


  unsigned int ExitBox = 1;
  unsigned int EntranceBox=9;
  unsigned int OldIndex = 12;
  double * TempPtr = TestPointerArray[OldIndex];

  if (ExitBox < EntranceBox)
  {
    Boxes[ExitBox].NumberPoints--;
    Boxes[EntranceBox].NumberPoints++;
     //Swap final element of this box into old position
     TestPointerArray[OldIndex] = *(Boxes[ExitBox+1].TestArrayPointer-1);
     //Keep swapping start for end
     for(unsigned int BoxNum = ExitBox+1; BoxNum<EntranceBox &&
       BoxNum+1<=9;BoxNum++)
     {
        Boxes[BoxNum].TestArrayPointer=
      Boxes[BoxNum].TestArrayPointer-1;
        //Fill in new first with last element of old array.
    *(Boxes[BoxNum].TestArrayPointer)=
      *(Boxes[BoxNum+1].TestArrayPointer)-1;    
    std::cout <<"---------------------" << std::endl;
    for (unsigned int Counter = 0; Counter<100; Counter++)
       std::cout << "P: " << TestPointerArray[Counter] << " V: " 
             << *(TestPointerArray[Counter]) << std::endl;
     }
     Boxes[EntranceBox].TestArrayPointer=
      Boxes[EntranceBox].TestArrayPointer-1;
     *(Boxes[EntranceBox].TestArrayPointer) = TempPtr;
  }  

  for(unsigned int BoxNum = 0; BoxNum<=9;BoxNum++)
  {
    std::cout <<"---------------------" << std::endl;
    for(unsigned int Counter = 0; Counter<Boxes[BoxNum].NumberPoints; 
    Counter++)
      std::cout << "P: " <<Boxes[BoxNum].TestArrayPointer[Counter] 
      << " V: " 
            << *(Boxes[BoxNum].TestArrayPointer[Counter]) 
      << std::endl;

  }
}

Note the proper swapping!!


I'm not going to question your code because I can't really read it.

Regarding the l-value error, change:

(Boxes[BoxNum-1].TestArrayPointer-1) = ...

to

*(Boxes[BoxNum-1].TestArrayPointer-1) = ...

or even

Boxes[BoxNum-1].TestArrayPointer[-1] = ...

A calculated pointer is not an l-value, it must be dereferenced. In other words, you can't store anything by changing the address, you must store your value at the address.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜