我一直在寻找答案,但似乎找不到答案。 (我对C ++的经验相当有限)
在我的图书馆,我释放了一个字符串。 (太棒了,嗯?)
这就是出现问题的地方。我有一个包含char *的结构,可以在堆上分配,也可以不分配。虽然它是一个有效的指针,但它无法释放。
IE
char* s1 = "A String";
char* s2 = (char*)memcpy(malloc(9), s1, 9);
free(s2);
free(s1);
会导致“free(s1);”错误(正如它应该) 因为s1实际上不会需要被释放,(它不在堆上)如何以“可接受”的方式处理它? (在类似的主题上,“让它崩溃”的答案似乎不合理IMO)
因为结构不仅仅是由库创建的,所以不可能保证使用memcpy之类的东西正确复制字符串。
看到这是一个Windows库,我不需要担心使用ISO C的东西或标准的C函数。
答案 0 :(得分:6)
在C ++中,你根本不应该担心这一点。使用std::string
并让它自动为您管理内存。 Don't manage memory manually.
如果您要手动执行此操作,则需要自行管理资源,
答案 1 :(得分:2)
看到这是一个Windows库,请将参数设为 BSTR
。然后,您需要用户正确分配(使用SysAllocString
),并确保您使用a matching deallocator。
其他方法只是......糟糕。如果您的用户使用不同的编译器,那么即使他们使用free()
,您也不能malloc
字符串。
[注意:根据詹姆斯的请求从评论转换而来,这实际上只是his suggestions的最后一个案例的Windows特例
进一步说明:BSTR是Unicode。我有点记得看到一种方法来使用BSTR分配器来存储ANSI字符串,似乎SysAllocStringByteLen
这样做,但要注意将ANSI数据放在BSTR中对任何熟悉BSTR的人来说都是非常违反直觉的。
答案 2 :(得分:0)
您可以将malloc char *s1
添加为"A String"
作为值。之后,您可以免费s1
。
答案 3 :(得分:0)
这是编译时已知的事情。你看看代码,知道什么是免费的,什么不是。所以不要想办法把它推迟到运行时,因为除了在这种情况下你找不到办法的事实,这是用C ++做错事的错误方法。当您可以静态地执行此操作时,请静态执行此操作。
使用类型系统。使用RAII。
答案 4 :(得分:0)
将所有字符串存储在堆中,然后您就会知道它们都需要被释放。如果字符串存在于全局内存中,请将其复制到堆缓冲区。
答案 5 :(得分:0)
我过去做过类似的事情,在某些情况下我会使用堆栈分配的字符串,而在其他情况下我会使用堆分配的字符串,但它们最终会被传递给其他一些常用代码。
在这种情况下,我所做的就是有两个指针。一个是NULL或堆分配的字符串。另一个指针指向堆栈分配或与前者相同的堆分配内存。当你去做free()时,你只检查前一个指针。
当然,在暴露的API中,这看起来很糟糕。就我而言,它只是内部代码。
答案 6 :(得分:0)
对于涉及C ++内存分配的事情,智能指针非常棒。只是说'。
http://www.cplusplus.com/reference/std/memory/auto_ptr/
http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/smart_ptr.htm