小编Joh*_*ohn的帖子

谁删除了在构造函数中有异常的"新"操作期间分配的内存?

我真的不敢相信我找不到明确的答案......

在使用new运算符初始化C++类构造函数抛出异常后,如何释放分配的内存.例如:

class Blah
{
public:
  Blah()
  {
    throw "oops";
  }
};

void main()
{
  Blah* b = NULL;
  try
  {
    b = new Blah();
  }
  catch (...)
  {
    // What now?
  }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试这个时,b在catch块中是NULL(这是有道理的).

在调试时,我注意到conrol在它到达构造函数之前进入了内存分配例程.

这在MSDN网站上似乎证实了这一点:

当new用于为C++类对象分配内存时,在分配内存后调用对象的构造函数.

因此,请记住,b永远不会分配局部变量(即在catch块中为NULL),如何删除分配的内存?

得到一个跨平台的答案也很好.即,C++规范说什么?

澄清:我不是在讨论类在c'tor中分配内存然后抛出的情况.我很欣赏在这种情况下,不会召唤人.我在谈论用于分配THE对象的内存(Blah在我的例子中).

c++ constructor memory-leaks exception

49
推荐指数
4
解决办法
1万
查看次数

我应该处理超过MAX_PATH的文件吗?

刚做了一个有趣的案例.

我的软件报告了由于路径长于MAX_PATH而导致的故障.

该路径只是我的文档中的一个普通旧文档,例如:

C:\Documents and Settings\Bill\Some Stupid FOlder Name\A really ridiculously long file thats really very very very..........very long.pdf
Run Code Online (Sandbox Code Playgroud)

总长度为269个字符(MAX_PATH == 260).

用户没有使用外部硬盘或类似的东西.这是Windows托管驱动器上的文件.

所以我的问题是这个.我应该关心吗?

我不是说可以我对付长的路径,我问应该 I.是的,我知道一些的Win32 API的"\?\"的Unicode劈,但似乎这个技巧是不是没有风险(如它正在改变API解析路径的行为方式),并且所有API都不支持.

所以,无论如何,让我只说出我的立场/断言:

  1. 首先可能是用户能够打破此限制的唯一方法是,如果她使用的应用程序使用特殊的Unicode黑客攻击.这是一个PDF文件,所以她使用的PDF工具可能使用这个hack.
  2. 我尝试重现这个(通过使用unicode hack)并进行实验.我发现虽然文件出现在资源管理器中,但我无能为力.我无法打开它,我无法选择"属性"(Windows 7).其他常见的应用程序无法打开文件(例如IE,Firefox,记事本).资源管理器也不会让我创建太长的文件/目录 - 它只是拒绝.同上命令行工具cmd.exe.

基本上,人们可以这样看待它:一个胭脂工具允许用户创建一个许多Windows无法访问的文件(例如Explorer).我可以认为我不应该处理这个问题.

(顺便说一下,这不是对最短路径长度的批准投票:我认为260个字符是一个笑话,我只是说如果Windows shell和一些API无法处理> 260那么我为什么要这样做?).

那么,这是一个公平的观点吗?我应该说"不是我的问题"吗?

更新:刚刚让另一个用户遇到同样的问题.这次是一个mp3文件.我错过了什么吗?这些用户如何创建违反MAX_PATH规则的文件?

winapi max-path

30
推荐指数
4
解决办法
2万
查看次数

托管C++ .NET应用程序中未处理的托管异常访问冲突问题

这实际上是一个已经解决的问题,但它太深奥了,我以为我会为其他用户分享它.

也许其他人可能会提出理由?

无论如何,我正在研究用托管C++编写的"混合模式".NET应用程序,但是它与现有的本机库有很多链接.

问题是,未处理的托管异常最终成为Win32访问冲突.我的意思是,不是显示漂亮的.NET对话框,而是使用未处理的托管异常,而不是我将获得旧样式"未处理的win32异常发生在......"消息.

这是有趣的事情:如果我在调试器中启动应用程序,则会正确地拾取抛出的托管异常.即调试器向我显示该行.

但是,正常执行时,它将变为此访问冲突.在那一点附加调试器将产生很少的有用信息(它甚至不会显示合理的堆栈跟踪).

所以,对我而言,它表明在未处理的托管异常到达异常处理程序之前,本机代码中正在发生某些事情.

所以无论如何,我设法通过将我的项目与Visual Studio 2008生成的干净的新C++托管项目进行比较来解决问题.

解决方法是执行以下操作:

  1. 将/ SUBSYSTEM标志(项目属性 - >链接器 - >系统 - >子系统)/SUBSYSTEM:WINDOWS 更改为 "未设置"

  2. 从使用旧样式WinMain()切换到使用新样式main().

也就是过去

  int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
Run Code Online (Sandbox Code Playgroud)

它现在是

int main(array<System::String ^> ^args)
Run Code Online (Sandbox Code Playgroud)

[为什么我使用这个奇怪的_tWinMain?这是多年前在创建示例混合模式Windows应用程序时由Visual Studio .NET IDE生成的.它一直很好(直到现在)所以我从来没有打扰过它._tWinMain只是WinMain的一个宏]

我做了这个改变,问题就消失了.未处理的.NET异常现在被正确捕获,因此我现在可以实际调试它们.

我还对干净的示例C++应用程序进行了相反的更改,并证明了它是原因.

所以,我真正的问题是,到底发生了什么?

是不是只使用了旧式WinMain而不是新款main(array <String^>^)

我是否应该向微软报告此事(任何人都会关心;-))?

.net c++ mixed-mode exception-handling

15
推荐指数
1
解决办法
2314
查看次数

STL排序集,其中订单的条件可能会发生变化

我有一个定义了自定义顺序的C++ STL集.

这个想法是,当项目被添加到集合中时,它们会按照我的需要自然排序.

但是,我刚才意识到,排序谓词可以随着时间的推移而改变.

据推测,集合中的项目将不再有序.

真的有两个问题:

  1. 然后这些物品会出现故障是否有害?我是否正确地说,可能发生的最坏情况是新的条目可能被放入错误的地方(实际上我可以忍受).或者,这会导致崩溃,丢失条目等吗?

  2. 有没有办法"刷新"集合的顺序?您似乎无法在集合上使用std :: sort().我能想到的最好的方法是将内容转储到临时容器中并重新添加它们.

有任何想法吗?

谢谢,

约翰

c++ stl set

9
推荐指数
1
解决办法
5976
查看次数

混合模式C++/CLR应用程序中的内存泄漏

我在混合模式C++/CLR .NET应用程序中遇到内存泄漏问题.

(它是使用"/ clr"编译器设置链接到VS2008 C++/CLR Windows窗体应用程序的C++本机静态库)

典型行为:应用程序开始使用30 MB(私有内存).然后泄漏内存减慢,比如在模拟重负载下运行时每小时一MB.这模拟了数天或数周的应用程序.

我尝试使用几种工具来跟踪内存泄漏,包括Visual Studio CRT库附带的CRT调试内容.我还使用了商业泄漏检测工具("Memory Validator").

两者都报告在关机时可忽略不计的内存泄漏(一些小的条目,相当于我不担心的几KB).此外,我可以看到,在运行时,跟踪的内存似乎没有那么多(所以我不相信它只是被占用的内存,只在app退出时释放).我得到大约5 MB的列出内存(总计> 30MB).

设置工具(Memory Validator)以跟踪所有内存使用情况(包括malloc,new,虚拟内存分配和一大堆其他类型的内存分配).基本上,已选择要跟踪的内存的每个设置.

.NET镜像报告它使用大约1.5 MB的内存(来自perfmon).

这是最后一点信息:我们有一个版本的应用程序作为本机控制台应用程序运行(纯粹是原生的 - 根本不是CLR).这与混合模式的95%相同,除了没有UI的东西.这根本不会泄漏内存,并且在大约5MB的私有字节处达到峰值.

所以基本上我试图在这里得到的是,我认为任何本机代码都不会泄漏内存.

另一个难题:我发现这是指在2.0框架(我是)时混合模式应用程序中的内存泄漏:http://support.microsoft.com/kb/961870

不幸的是,细节非常稀疏,所以我不确定它是否相关.我确实尝试针对3.5框架而不是2.0但仍然有同样的问题(也许我没有做到这一点).

有人有什么建议吗?

一些可能对我有帮助的事情:

  • 是否还有其他类型的内存分配,我没有跟踪?
  • 为什么数字不加起来?我得到5 MB的CRT内存使用量,1.5 MB的.NET内存,那么为什么整个应用程序使用30MB的私有字节呢?这一切都绑在.NET框架中吗?为什么我在泄漏工具中看不到这些?.NET框架不会显示为某种分配的内存吗?
  • 任何其他泄漏检测工具适用于混合模式应用程序?

谢谢你的帮助

约翰

.net c++ mixed-mode memory-leaks

9
推荐指数
1
解决办法
7582
查看次数

文件内容损坏的原因

我在野外有一个应用程序反复出现问题.

它有一个相当简单的XML文件,它偶尔会丢弃,就像每30分钟一样.

数据文件通常非常小 - 例如<5KB.

它没有锁定文件 - 它只是每次从头开始重新创建它.

我很幸运地看到问题发生在测试机器上,我观察到的是文件已损坏并设置为"nulls"(即十六进制中的00).真正奇怪的是它与它应该具有的正确长度完全相同.

我在保存过程中一直非常小心:

  1. 我将xml写入同一目录中的临时文件,因为我要真正保存它
  2. 我使用MOVEFILE_WRITE_THROUGH设置执行Win32 MoveFile()(因此它应该阻塞直到移动真正完整),移动文件以替换现有数据文件

我甚至锁定Mutex以确保这不是线程问题.

它通常不会发生,例如1000个用户中的1个.

现在我在过去观察到数据文件在写入过程中被电源故障或BSOD损坏,我看到像32kb的文件都是NULL.

但考虑到写入期间出现电源故障的可能性,以及特别是因为我正在使用MOVEFILE_WRITE_THROUGH,它似乎比我预期的要发生得更多.

有任何想法吗?

约翰


一些问题的答案:

  • 问:为什么不直接写入文件A:我避免这种情况使软件不易受到电源故障的影响.例如,你正在编写文件和崩溃/ powerfail/BSOD的一半,那么你肯定有一个损坏的文件.执行临时文件写入然后执行移动是确保尽可能执行原子文件操作的常用且简单的方法(尽管在不使用NTFS特定API的情况下尽可能合理).我应该说该软件是一个归档/备份系统,所以我必须更加注意数据一致性,而不是其他应用程序.

  • 问:这是否在正常操作期间发生?

  • 答:由于这个问题在野外发生,我只是在处理一些线索,所以我不确定.我可以说该软件在99.9%的时间内可靠运行.我猜这是我的问题的核心:这只是由BSOD /电源故障引起的随机不幸还是一个错误?

  • 问:什么环境/操作系统:

  • 答:XP,Vista,7,Server 200X.最有可能是NTFS,但可能是FAT32

  • 问:我在移动之前关闭了文件吗?

  • 答:是的.在使用MoveFile之前,我正在使用C++流并调用close()

  • 问:还有哪些进程正在访问该文件?

  • 答:没有我管理.显然,我无法控制病毒检查程序,文件夹同步器等.该文件位于用户计算机的AppData\Local文件夹中.

c++ windows file-io winapi corruption

7
推荐指数
1
解决办法
2305
查看次数

JVM使用超过最大堆的LOT

我们遇到的问题是JVM比max -Xmx使用的要多得多.

我们正在使用-Xmx2048,它目前正在使用17GB的OS内存.

我意识到JVM可以使用超过最大堆的使用,但我们使用15GB以上看起来很疯狂.

顶部转储如下所示:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                          
30477 root      20   0 22.683g 0.017t  18536 S   0.7 29.1  27:43.44 java -Xmx2048M -Xms1024M -XX:MaxPermSize=256M -XX:ReservedCodeCacheSize=128M  ....
Run Code Online (Sandbox Code Playgroud)

(注意它使用的是0.017TB或17GB).

我尝试使用jmap进行调试:

sudo jmap -J-d64 -heap 30477

Attaching to process ID 30477, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.75-b04

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio = 0
   MaxHeapFreeRatio = 100
   MaxHeapSize      = 2147483648 (2048.0MB)
   NewSize …
Run Code Online (Sandbox Code Playgroud)

java memory jvm

7
推荐指数
2
解决办法
1041
查看次数

使用CloseHandle"双关闭"句柄是否安全?

不止一次调用CloseHandle会有什么影响?

文档说"你不应该",但我认为我有一个现实的案例,其中一个句柄可能是外部关闭的命名管道(见帖子的结尾).

在这种情况下,CloseHandle在调试模式下抛出异常,这表明开发人员认为这很严重,但文档并不完全清楚.

(礼貌请求:请避免回答"只是不要!":-).当然,应该避免不止一次关闭手牌,当然还有很好的技巧来帮助解决这个问题:如果你不这样做,我只会感兴趣.

我听说有些人建议,如果操作系统很快重复使用句柄,你最终可能会关闭另一个不同的句柄.

这可能吗?

Windows如何选择句柄ID?

是否可以保证手柄值的重复使用频率如何?

(例如,TCP确保端口号不能在特定时间范围内重用).

你可以关闭句柄类型的句柄吗?例如,我是否可以认为我正在关闭管道但最终关闭一个事件?

谢谢!

约翰

(上下文:我在客户端/服务器模型中使用命名管道.在我看来很难确保确保一方确保关闭句柄,例如在进程崩溃/被杀案件中.也许我错了,但肯定MSDN示例代码在我看来似乎允许客户端关闭共享句柄,然后当服务器试图关闭它时,它已经关闭).

winapi handles

6
推荐指数
1
解决办法
3006
查看次数

以编程方式强制图标在 Windows 7 中的“通知区域”/“系统托盘”中可见

Windows 7 允许用户在“通知区域”(又名系统托盘)中隐藏/显示图标。

默认情况下,我认为它们是隐藏的?

是否可以以编程方式(通过应用程序或通过安装程序)强制显示图标?

编辑:我不是在寻找覆盖用户请求的方法。我要问的是,有没有办法最初出现,即使用户然后永久地隐藏了你。即,我们可以让它“选择退出”而不是“选择加入”吗?

systray windows-7

5
推荐指数
1
解决办法
3464
查看次数

使用SSL密码哈希

好吧,这可能听起来像一个奇怪的问题.在跳我之前请仔细阅读好吗?;-)

想象一下这种情况:

  1. 我们有一个服务器和一个客户端.
  2. 他们使用SSL连接.
  3. 客户端使用密码在服务器上创建帐户
  4. 但是,他实际通过网络传递给服务器的是密码的哈希(+盐)(不是密码)
  5. 服务器在DB中保存此接收的密码哈希值(使用盐哈希)
  6. 在登录时,要进行身份验证,用户重新发送密码哈希值(不是密码!).

好的,是的,我意识到这听起来很奇怪.是的,整个会话都在SSL中,所以你可以发送密码明文.是的,我意识到可以安全地存储明文密码.

以下是我的观点:对我们的业务来说,真实地说"我们永远不会知道您的密码"是​​有用的.

注意我不是说"我们不以明文形式存储您的密码",但我们真的,从来没有,知道它; 你永远不会把它给我们.

(想要这个的原因是不相关的,足以说用户的密码用于其他东西,例如文件加密).

是的,我意识到你可能会说正常的做法是"在你进行散列时,密码只能在内存中以明文形式显示5ms",但这更多是关于否定性.即,我们可以说100%我们甚至没有收到您的密码.

好的,这就是问题所在:

  • 以前有人做过或听说过这种事吗?

  • 这样做有什么安全隐患?

我很难看到一个缺点.例如:

  • 没有重播攻击(因为会话使用SSL加密,攻击者无法看到哈希)
  • 无法查看数据库,因为哈希本身就是哈希...,哈希

好的,你现在可以跳我:)

想法,欢迎评论.

谢谢,

约翰

更新:只是想澄清:我并不是说这在某种程度上改善了身份验证过程的安全性.但是,它允许用户的"真实"密码保持秘密,即使是从服务器.因此,如果真实密码用于加密文件,则服务器无权访问.

我完全满足于我想要这个的原因,问题是它是否会妨碍身份验证过程的安全性.

authentication hash ssl cryptography http-digest

5
推荐指数
1
解决办法
1453
查看次数