Необработанное исключение с приложением С++ в сборке выпуска Visual Studio 2008 — возникает при возврате из функции

У меня есть (довольно большое) приложение, которое я написал на C++, и до недавнего времени оно отлично работало вне Visual Studio с момента сборки релиза. Однако теперь, всякий раз, когда я запускаю его, он говорит: «Необработанное исключение по адресу 0x77cf205b в myprog.exe: 0xC0000005: место записи нарушения прав доступа 0x45000200.», и приводит меня к «crtexe.c» в строке 582 («mainret = main(argc, argv, envp);"), если я попытаюсь отладить его. Обратите внимание, что эта проблема никогда не проявляется, если я запускаю свой исполняемый файл отладки вне Visual Studio или если я запускаю свою отладочную или выпускную сборку в Visual Studio. Это происходит только при запуске сборки релиза вне Visual Studio.

Я просмотрел и поместил в него множество printfs и пару while(1), чтобы увидеть, когда он на самом деле разбился, и обнаружил, что нарушение прав доступа происходит именно в тот момент, когда значение возвращается из функции (я возврат указателя на объект). Я не совсем понимаю, почему я получаю нарушение доступа в момент его возврата, и, похоже, не имеет значения, что я возвращаю, поскольку это все еще происходит, когда я возвращаю 0.

Момент, когда он начал падать, был, когда я добавил функцию, которая много читает из файла, используя ifstream. Я открываю поток каждый раз, когда пытаюсь прочитать новый файл, и закрываю его, когда заканчиваю чтение.

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

Спасибо за вашу помощь, и если я что-то пропустил, дайте мне знать.

РЕДАКТИРОВАТЬ: Новая информация

Ну, я удалил всю функцию и заменил ее на:

IndexedMesh * loadObj(char * objName)
{

ifstream fp_in;
fp_in.open("lol.bmp", ios::in);

fp_in.clear();
fp_in.close();

IndexedMesh * mesh = new IndexedMesh();

printf("finished");


return mesh;
}

Я также пробовал с «вернуть 0» и «вернуть новый IndexedMesh ()». Все в порядке, пока вы не вставите материал ifstream. У меня есть 2 других ifstream, открытых в разных функциях (доступ к совершенно разным файлам). Может ли это быть проблемой?

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


person Rich    schedule 09.04.2010    source источник
comment
Нам нужен код. Без кода никто здесь не поймет, почему вы получаете нарушение прав доступа.   -  person Billy ONeal    schedule 10.04.2010
comment
Когда вы возвращаетесь, вы оформляете отпуск; ret, который очищает стек и возвращается к сохраненному адресу, указывающему место возврата вызывающей функции. Если вы зачеркнете адрес возврата и установите для него что-то вроде 0xFFFFFFFF, return 0; попытается перейти к 0xFFFFFFFF. Так что вы, вероятно, где-то сломали стек.   -  person ta.speot.is    schedule 10.04.2010


Ответы (3)


Момент, когда он начал падать, был, когда я добавил функцию, которая много читает из файла, используя ifstream. Я открываю поток каждый раз, когда пытаюсь прочитать новый файл, и закрываю его, когда заканчиваю чтение.

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

person ChrisF    schedule 09.04.2010
comment
@Rich - поместите этот код в вопрос, без форматирования трудно понять, что это такое - person ChrisF; 10.04.2010

Вероятно, вы перебираете что-то, хранящееся глубоко в стеке.

Держу пари, что если бы вы поместили это в верхнюю часть кода:

int my_main(int argc, char * argv[], char * envp[]);

int main(int argc, char * argv[], char * envp) {
    char ** a;
    char ** e;
    a = malloc(argc+1); // note: you should test the results for NULL
    e = malloc(1+count(envp) ) ;// I'm not writing code to count it, but it's easy

    int i = 0;
    while (argv[i++]) {
       a[i] = strdup(argv[i]);
    }
    a[i] = argv[i]; // argv[i] is NULL and already in a register

    // do the same thing for envp

    return my_main(argc, a, e);
}
#define main my_main

тогда то, что разрушает ваш стек, вместо этого приведет к разрушению этой дублированной среды. Это не гарантировано, и это не решение вашей проблемы, но не так сложно.

person nategoose    schedule 09.04.2010

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

На самом деле я дошел до изменения функции, чтобы просто объявить ifstream, а затем вернуть 0. Я «исправил» это, объявив ifstreams как указатели и обновив их. Если я удалял указатель, он снова вылетал, поэтому мне приходилось устанавливать его на 0 (leeeeak).

Если бы кто-нибудь мог просветить меня, почему это происходит, это было бы здорово. Хотя я просто счастлив, что это работает сейчас, я бы предпочел знать, почему ..

person Rich    schedule 10.04.2010
comment
Проблемы, которые волшебным образом уходят, волшебным образом возвращаются, причем в самый неподходящий момент. Особенно это касается проблем с перезаписью стека. Не радуйтесь, пока не узнаете или не объясните, в чем на самом деле была первоначальная проблема. - person dthorpe; 13.04.2010