2010-06-18 45 views
2

我的开发环境是[Windows 7; visual studio 2010; 86]。使用new/delete,但不使用malloc/free在C++代码中崩溃

我有一个为服务器2003长时间后建立的dll。当我在我的项目中使用它并按照新/删除序列使用类时,应用程序在删除调用期间崩溃。即使在新建和删除之间没有任何其他调用,我也进行了验证。当我用malloc/free替换new/delete时,没有崩溃。如果我仅仅声明一个没有新的类的实例,当范围退出时不会发生崩溃。

任何想法可能会出错?这是我们公司的内部图书馆,所以我将无法命名它和其他类似的东西。

附加信息: 要首先使用此库,我必须关闭VS功能“将wchar_t作为内置类型”。

代码很简单

{ 
    CLogger * myLog = new CLogger(); 
    delete myLog; // Crash happens here 
} 

{ // No crash here 
    CLogger MyLog; 
} 

{ 
    CLogger * myLog = (CLogger *) malloc (sizeof(CLogger)); 
    free (myLog); // This does not crash. 
} 

这是专利文献,我不能发布的构造函数和析构函数。

+1

请张贴代码。有一百万件事情可能是错误的,其中没有一件可以在不查看代码的情况下确定。 – 2010-06-18 16:49:00

+0

请向我们展示您使用新建和删除的实际代码行。这个类的构造函数和析构函数也会有帮助。 – 2010-06-18 16:50:54

+0

代码是简单 { CLogger * myLog =新CLogger(); delete myLog; //碰撞发生在这里 } {//此处没有崩溃 CLogger MyLog; } { CLogger * myLog =(CLogger *)malloc(sizeof(CLogger)); free(myLog); //这不会崩溃。 } 这是专利文献,我不能发布的构造函数和析构函数。 – Zhinkaas 2010-06-18 16:53:19

回答

7

删除不仅仅是释放内存:它也在之前调用析构函数。这意味着在该类的析构函数中肯定有什么不好的。

如果在析构函数中发生未捕获的异常,则整个过程将退出(*)。 作为评论如下(感谢良好的反馈),这是过于简单化这里是一个很好的链接了解详情: throwing exceptions out of a destructor

我会建议你把一个

try {} catch (std::exception& e){} catch(...) {} 

析构函数和对数内了解发生了什么,或者更好地让它通过调试器,并选择停止在发生异常的位置。

然后,应该很容易找出不同的东西。只是从我的猜测,它可能是一些注册表访问权限或文件访问权限,其中一些变化从服务器2003引入到Windows 7中。

+1

这是对从析构函数中抛出异常时发生的过度简化。这绝对是值得一提的那些需要为此引起呼叫终止的确切条件() 2010-06-18 16:59:05

+0

如果在堆栈平仓由于另一个异常发生时未捕获的异常将只终止进程。 – 2010-06-18 17:01:17

3

我应用了我的心理调试技巧,建议您使用delete您应该在哪里使用delete[]

推理:如果你能平凡取代newmalloc,你可能分配基本类型的数组,而不是一个对象,并天真地对对象分配和数组分配是假设代替free使用delete在C++中也是一样。 (他们不是。)

+1

从我的经验,应该可能会创建泄漏,因为只有第一个数组对象的构造函数被调用,但没有崩溃。不过,我认为这不是问题,而是一个好建议。 – jdehaan 2010-06-18 16:53:26

+0

Zhinkaas必须修改涉及'wchar_t'的设置,这也为您的观点增加了可能的证据。 – JAB 2010-06-18 16:54:25

+0

我认为这更多的是因为wchar_t以另一种方式装饰,如果你使用它作为内置的并且可能使用C++链接到另一个dll并且将va将签名变成短裤以便链接不能正确编译很多或未解决的符号。 @Zinkaas纠正我,我错了。 – jdehaan 2010-06-18 17:01:46