Ошибка удаления C ++ - исключение _unlock_fhandle? - PullRequest
1 голос
/ 18 мая 2011

У меня прямая проблема, но я не понимаю, почему она у меня есть.

Я был бы очень признателен за любые идеи.

Я написал этот код, чтобы проверить, правильно ли я создавал и использовал библиотеки DLL в Visual Studio 2010 под Win 7 64bit, которые могли выполняться в Windows XP. Код выполняется правильно, и поскольку это небольшая тестовая программа, освобождение выделенной памяти не критично, но, безусловно, будет в будущем.

Я неявно вызываю DLL, как я уже сказал, она работает нормально. Когда я добавляю строку «delete dllMsg;» в toyUseDLL.cpp, она падает, и отладчик показывает _unlock_fhandle в osfinfo.c.

Если это уместно, я компилирую программу с / MT для встраивания библиотеки времени выполнения (по небольшому количеству несущественных причин).

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

Спасибо за любую помощь, я довольно новичок в C ++ и уже нашел большую помощь на этом сайте, так что спасибо всем, кто писал в прошлом !! : -)

msgDLL.h

#include <string>
using namespace std;

namespace toyMsgs {
    class myToyMsgs {
        public:
        static __declspec(dllexport) string* helloMsg(void);
        static __declspec(dllexport) string* goodbyeMsg(void);
    };
}

msgDLL.cpp

#include <iostream>
#include <string>
#include "msgDLL.h"

using namespace std;

namespace toyMsgs {
    string* myToyMsgs::helloMsg(void) {
        string *dllMsg = new string;
        dllMsg->assign("Hello from the DLL");
        cout << "Here in helloMsg, dllMsg is: \"" << *(dllMsg) << "\"" << endl;
        return (dllMsg);
    }

    string* myToyMsgs::goodbyeMsg(void) {
        string *dllMsg = new string;
        dllMsg->assign("Good bye from the DLL");
        cout << "Here in goodbyeMsg, dllMsg is: \"" << *(dllMsg) << "\"" << endl;
        return (dllMsg);
    }
}

toyUseDLL.cpp

#include <iostream>
#include <string>

#include "stdafx.h"
#include "msgDLL.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[]) {
    string myMsg;
    string *dllMsg;

    myMsg.assign ("This is a hello from the toy program");
    cout << myMsg << endl;

    dllMsg = toyMsgs::myToyMsgs::helloMsg();
    cout << "Saying Hello? " << *(dllMsg) << endl;
    delete dllMsg;

    myMsg.assign ("This is the middle of the toy program");
    cout << myMsg << endl;

    dllMsg = toyMsgs::myToyMsgs::goodbyeMsg();
    cout << "Saying goodbye? " << *(dllMsg) << endl;

    myMsg.assign ("This is a goodbye from the toy program");
    cout << myMsg << endl;

    return 0;
}

Вывод программы:

This is a hello from the toy program
Here in helloMsg, dllMsg is: "Hello from the DLL"
Saying Hello? Hello from the DLL
This is the middle of the toy program
Here in goodbyeMsg, dllMsg is: "Good bye from the DLL"
Saying goodbye? Good bye from the DLL
This is a goodbye from the toy program

Ответы [ 2 ]

2 голосов
/ 19 мая 2011

Проблема в том, что вы используете / MT для компиляции вашего EXE и DLL.Когда вы используете / MT, каждый исполняемый файл получает свою собственную копию библиотеки времени выполнения C, которая является отдельным и независимым контекстом.CRT и стандартные типы библиотек C ++ не могут безопасно передаваться через границу DLL, когда обе библиотеки DLL скомпилированы / MT.В вашем случае строка выделяется одним CRT (в его частной куче ОС) и освобождается EXE-файлом (который имеет другую кучу), вызывая соответствующий сбой.

Чтобы заставить программу работать, просто скомпилируйте/ MD.

Общие советы: / MT почти никогда не подходит (по большому количеству относительно важных причин, включая стоимость памяти, производительность, обслуживание, безопасность и другие).

Martyn

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