C++和C混合编程——windows已在XX.exe中触发一个断点

来源:互联网 发布:java存储数据的方法 编辑:程序博客网 时间:2024/06/03 16:31

进来开发一个新功能需要使用C++和C混合编程,这其实也不难,相关方法网络上已经有详细的讲解。我遇到的问题就是编译,链接都没有问题,但在运行时出现【windows已在XX.exe中触发一个断点,其原因可能是堆被损坏,这也说明xx.exe中或它锁加载的任何dll中有bug】。其中C写的代码是一个动态链接库,这个问题就是我将C的编译选项由【使用MDd(多线程调试 DLL)】运行时库修改为【使用MTd(多线程调试)】运行时库引起的,代码没有任何修改,C++代码设置的是【使用MTd(多线程调试)】运行时库。


首先,我将C写的动态链接库运行时库设置还原之后,问题没有了。但这不是能说代码没有问题,所以还是慢慢查找原因,最后定位到是一个释放指针的地方出现的问题。大概原型是这样的:


C代码中:

char* getName()

{

return strdup("XXXXXXXXX");

}


C++代码中:

void test()

{

char *p = getName();

if(p)

free(p);

}


问题就出现在free(p)这个地方。这个地方我就不太理解了,然后网上查找了一下原因,是如下描述的:

该问题主要是关于DLL与进程的地址空间的问题(引用<核心编程>>中的一段话):

单个地址空间是有一个可执行模块和若干个DLL模块组成的,这些模块中有些可以链接到静态版本的C/C++运行时库,有些可以链接到一个DLL版本的运行时库,而有些模块(如果不是用C/C++编写)则根本不需要C/C++运行时库,许多开发人员经常会犯一个常见的错误,因为他们忘记了若干个C/C++运行时库可以存在于单个地址空间中。如果EXE和DLL都链接到DLL的C/C++运行时库,那么上面的代码将能够很好的运行。但如果有两个模块中的其中一个或者两个链接到静态C/C++运行时库,那么对于delete或者free的操作就会失败

解决办法:

在C代码中提供销毁指针的接口,由C++中调用该接口释放空间,销毁指针。经过这样修改之后,无论怎样修改运行时库选项,不会出现该问题。该问题虽小,平时不太做C++与C混合编程,但对自己的感触还是很大的。一个可供其他模块调用的代码,自身接口的完整性是非常重要的。



原创粉丝点击