Как предотвратить копирование строки дикого указателя - PullRequest
0 голосов
/ 25 октября 2010

Моя программа прерывается с перебоями, когда она пытается скопировать массив символов, который не заканчивается символом NULL ('\ 0').

class CMenuButton {
   TCHAR m_szNode[32];
   CMenuButton() {
     memset(m_szNode, '\0', sizeof(m_szNode));
   }
};
int main() {
  ....
  CString szTemp = ((CMenuButton*)pButton)->m_szNode; // sometime it crashes here
  ...
  return 0;
}

Я подозревал, что кто-то не скопировал символ с хорошим концомна '\ 0', и это закончилось так:

            Stack
m_szNode    $%#^&!&!&!*@*#&!(*@(!*@@&#&*&@@!^&*&#(*!@*((*&*SDFKJSHDF*(&(*&(()(**

Можете ли вы сказать мне, что происходит и что я должен сделать, чтобы предотвратить копирование дикого указателя?Помощь будет очень признательна!

Думаю, я не могу проверить, равен ли массив символов NULL перед копированием ...

Ответы [ 3 ]

3 голосов
/ 25 октября 2010

Я подозреваю, что ваша настоящая проблема может заключаться в том, что pButton является неверным указателем, поэтому сначала проверьте это.

Единственный способ быть на 100% уверенным в правильности указателя и указыватьправильно подобранный / выделенный объект никогда не должен использовать указатели, которые вы не создали, и никогда не принимать / возвращать указатели.Вместо этого вы будете использовать куки и искать свой указатель в каком-то виде поиска куки -> указателя (например, в хеш-таблице).По сути, не доверяйте пользовательскому вводу.

Если вас больше волнует поиск ошибок и менее 100% безопасность от таких вещей, как атаки переполнения буфера и т. Д., Вы можете использовать менее агрессивный подход.В сигнатуре вашей функции, где вы в настоящее время используете указатели на массивы, добавьте параметр размера.Например:

void someFunction(char* someString);

Становится

void someFunction(char* someString, size_t size_of_buffer);

Кроме того, принудительно завершайте массивы / строки в ваших функциях.Если вы достигли конца, и он не завершен нулем, обрежьте его.

Сделайте так, чтобы вы могли указать размер буфера при их вызове, вместо того, чтобы вызывать strlen (или эквивалентный) для всехваши массивы перед вызовом.

Это похоже на подход, использованный «безопасными строковыми функциями», созданными Microsoft (некоторые из которых были предложены для стандартизации).Не уверен, что это идеальная ссылка, но вы можете зайти в Google за дополнительными ссылками:

http://msdn.microsoft.com/en-us/library/ff565508(VS.85).aspx

2 голосов
/ 25 октября 2010

Есть две возможности:

  1. pButton не указывает на CMenuButton так, как вы думаете, а приведение вызывает неопределенное поведение.
  2. Код, который устанавливает m_szNode, является неправильным, переполняет заданный размер 32 символа.

Поскольку вы не показали нам ни одного фрагмента кода, трудно понять, что не так. Ваша инициализация m_szNode выглядит нормально.

Есть ли причина, по которой вы не выбрали CString для m_szNode?

0 голосов
/ 26 октября 2010

Мой подход заключается в том, чтобы сделать m_szNode приватным членом в CMenuButton и явно NULL - определить его в методе мутатора.

class CMenuButton {
  private:
    TCHAR m_szNode[32];

  public:
    void set_szNode( TCHAR x ) {
        // set m_szNode appropriately
        m_szNode[ 31 ] = 0;
     }
};
...