Причудливая ошибка указателя C ++ MSVC6 - PullRequest
2 голосов
/ 07 марта 2011

Эта ошибка убивает меня.Я значительно упростил код (это виртуальные функции в классе, если это вообще помогает), но в этом суть.Я передаю указатель и по какой-либо причине вызывающая функция не получает того же значения.

Заранее спасибо.

bool getTable( int tableNum, DataTable* outputTable )  
{  
  // ... unrelated work ...
  outputTable = new DataTable();  
  cout << "outputTable= " << outputTable << endl;  
  return true;  
}  

bool storeTable( int tableNum )  
{  
  // ...
  DataTable* theTable;  
  bool isWorking = getTable( tableNum, theTable );  
  cout << "theTable= " << theTable << endl;
  // ...  
  return isWorking;  
 }  

Вывод для этого:

outputTable= 01ED8C20  
theTable= CCCCCCCC

Если я пытаюсь использовать таблицу, я получаю исключение нарушения прав доступа.

Еще раз спасибо.

Ответы [ 5 ]

3 голосов
/ 07 марта 2011

Две вещи:

  1. Вы передаете указатель по значению . скопировано в функцию, но указатель изменяется на local .Если вы хотите изменить указатель, вам нужно передать его по ссылке :

    bool getTable(int tableNum, DataTable*& outputTable)
    

    Еще лучше, вернуть вновь созданный объект и избавиться от (казалось бы бесполезным?) bool возвращаемое значение.

  2. Избавиться от VS6.Он древний, подвержен ошибкам и по существу не может справиться с современным C ++.Фактически, заставит написать вам плохой код C ++, потому что для хорошего идиоматического кода C ++ требуются функции, которые не работают в VC ++ 6.Кроме того, IDE просто на десятилетие отстает от современных стандартов юзабилити.

2 голосов
/ 07 марта 2011

Вы не вернете outputTable из getTable. Вместо этого вы возвращаете true. Вы назначаете таблицу, которую вы строите, временной переменной, которую вызывающий никогда не увидит. Вместо этого ее переменная theTable остается унифицированной.

Вы должны либо вернуть его (разумная опция), либо передать указатель на указатель / ссылку на указатель (сложная опция):

DataTable *getTable(int tableNum)  
{
    // ... unrelated work ...
    DataTable *outputTable = new DataTable();  
    cout << "outputTable= " << outputTable << endl;  
    return outputTable;
}

и вернуть 0 (нулевой указатель) вместо false, если что-то пойдет не так. Не забудьте проверить это, если это может произойти. Бросать и ловить исключение может быть даже лучше.

1 голос
/ 07 марта 2011
bool getTable( int tableNum, DataTable* outputTable )  

outputTable - переменная-указатель, которая существует только во время выполнения этой функции.

Назначение вновь созданного объекта этому указателю - это просто повторное наведение указателя на вашу новую переменную, оно не изменяет память, на которую outputTable указывает в данный момент.

Если вы хотите изменить «внешний мир» в этой функции, вам, вероятно, нужно объявить свою функцию следующим образом и изменить код внутри, как необходимо.

bool getTable( int tableNum, DataTable** outputTable )

(Хотя ссылки на C ++, вероятно, более идиоматичны.)

1 голос
/ 07 марта 2011

Вы только что создали локальную копию указателя.Передайте его как ссылку или указатель на указатель.Например:

bool getTable( int tableNum, DataTable*& outputTable )
0 голосов
/ 07 марта 2011

C / C ++ передается по значению, а не по ссылке.

Вы передаете значение таблицы в функцию, а затем обновляете ее, что не меняет значение в вызывающей функции.

Вам нужно сделать это:

getTable (tableNum, &theTable);

А в функции getTable нужно сделать:

*outputTable = new DataTable()

В качестве альтернативы вы можете изменить объявление функции getTable () для передачи по ссылке:

bool getTable( int tableNum, DataTable* &outputTable )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...