C ++ Visual Studio Runtime Ошибка - PullRequest
       13

C ++ Visual Studio Runtime Ошибка

2 голосов
/ 19 ноября 2008

Может кто-нибудь объяснить мне, что это значит?

"Ошибка проверки времени выполнения # 0 - значение ESP не было должным образом сохранено при вызове функции. Обычно это является результатом вызова функции, объявленной с одним соглашением о вызовах, с указателем функции, объявленным с другим соглашением о вызовах. «

Ответы [ 4 ]

7 голосов
/ 19 ноября 2008

При вызове функции компилятор должен выдвинуть некоторые аргументы в стек или поместить их в некоторые регистры. Тело функции изменит некоторую ячейку памяти (или регистр), чтобы содержать возвращаемое значение. Затем он вернется к блоку кода в месте, хранящемся «где-то» в стеке.

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

Если вызывающая сторона делает это не так, как ожидает функция, все может пойти не так (место возврата не в ожидаемой позиции стека).

ESP - это обычно регистр, содержащий адрес текущего фрейма стека. Этот регистр используется в сочетании с индексами для получения аргументов в теле функции. При возврате вершина стека обычно сбрасывается в ESP, и процессор переходит к месту, например, в. ESP + 1.

Вещи, которые могут вызвать это:

  • кто-то записал значения стека и изменил место возврата (например, переполнение буфера)
  • вызывающий абонент имел другое соглашение о вызовах, чем вызываемый
3 голосов
/ 19 ноября 2008

Возможность № 1 - ваш объект получил псевдоним неправильно. Это означает, что компилятор ошибочно приводил объект неправильно, чаще всего для оптимизации.

Возможность # 2 при использовании ссылки на недопустимый объект.

Возможность # 3 что-то совершенно не связанное сломало ваш стек, вероятно переполнение буфера.

Без примера кода. Сложно предсказать эти возможности, но они охватывают 90% того, что может происходить.

1 голос
/ 19 ноября 2008

Это означает, что значение в регистре ESP процессора не было правильно восстановлено после вызова функции.

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

Я видел эту ошибку, когда между вызывающим кодом и вызываемым кодом возникает разногласие по поводу того, кто настраивает esp. Посмотрите внимательно на то, как объявлена ​​функция, особенно если она находится в отдельной библиотеке или dll.

0 голосов
/ 19 ноября 2008

Это обычно имеет место при приведении указателя функции для закрытия компилятора при вызове Windows API, такого как DialogBox:

DialogBox(hInstance, MAKEINTRESOURCE(MY_DIALOG), hWnd, &dlgProc);

Windows немного странная в том смысле, что все функции определены с соглашением о вызовах stdcall, в отличие от cdecl, по умолчанию в C. Поэтому все функции, которые должны быть переданы в API Windows, должны быть определены с WINAPI STDCALL):

INT_PTR WINAPI dlgProc(HWND, UINT, WPARAM, LPARAM);

Если вы пропустите это и вместо этого определите свой dlgProc как:

INT_PTR dlgProc(HWND, UINT, WPARAM, LPARAM);

Ваш код не скомпилируется, и у вас может возникнуть соблазн просто выключить чертов компилятор:

DialogBox(hInstance, MAKEINTRESOURCE(MY_DIALOG), hWnd, (DLGPROC)&dlgProc); // be a DLGPROC already, dammit!!

Не делай этого. Программа вылетит. Компилятор твой друг. Оператор приведения в стиле C - нет. Компилятор попытался сказать вам, что это должно было случиться. И это было правильно. Послушай это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...