C++ 检查是否可以释放指针
我到处寻找答案,但似乎找不到答案。(我在C++方面的经验相当有限) 在我的图书馆里,我释放了一个字符串。(太棒了,是吧?) 这就是问题所在。我有一个包含char*的结构,可以在堆上分配,也可以不分配。虽然它是一个有效指针,但无法释放它 即 将在“free(s1);”上导致错误(应如此) 因为s1实际上不需要释放(它不在堆上),所以我如何以“可接受”的方式处理它?(在类似的话题上,“让它崩溃”的答案在国际海事组织看来并不合理) 由于结构不是由库单独创建的,因此无法保证使用memcpy之类的东西正确复制字符串C++ 检查是否可以释放指针,c++,memory,pointers,free,C++,Memory,Pointers,Free,我到处寻找答案,但似乎找不到答案。(我在C++方面的经验相当有限) 在我的图书馆里,我释放了一个字符串。(太棒了,是吧?) 这就是问题所在。我有一个包含char*的结构,可以在堆上分配,也可以不分配。虽然它是一个有效指针,但无法释放它 即 将在“free(s1);”上导致错误(应如此) 因为s1实际上不需要释放(它不在堆上),所以我如何以“可接受”的方式处理它?(在类似的话题上,“让它崩溃”的答案在国际海事组织看来并不合理) 由于结构不是由库单独创建的,因此无法保证使用memcpy之类的东西正确
因为这是一个Windows库,我不需要担心使用ISOC的东西或标准的C函数。C++中的< P>,你根本不必担心这个。使用
std::string
并让它自动为您管理内存
如果要手动执行此操作,则需要通过
- 让库的用户自己管理内存,或
- 要求用户告诉您如何管理内存,或
- 告诉用户您将如何管理内存,然后期望用户遵守
char*s1
并将一个字符串作为值放置。在此之后,您可以释放s1
这是编译时已知的事情。你看了代码,知道什么是免费的,什么是不免费的。所以不要想办法把它推迟到运行时,因为除了在这个例子中你找不到一个方法,它是在C++中做错误的方式。当你可以静态地做的时候,就静态地做
使用类型系统。使用RAII。将所有字符串存储在堆中,然后您就会知道它们都需要释放。如果字符串以全局内存的形式存在,请将其复制到堆缓冲区。我以前也做过类似的事情,在某些情况下使用堆栈分配的字符串,在其他情况下使用堆分配的字符串,但它们最终会传递到其他一些公共代码
在这种情况下,我所做的是有两个指针。一个是NULL,或者是堆分配的字符串。另一个指针指向堆栈分配的内存或与前者相同的堆分配内存。在执行free()时,只检查前一个指针
当然,在一个公开的API中,这看起来很糟糕。在我的例子中,它只是内部代码。鉴于这是一个Windows库,请将参数设为一个BSTR
。然后,您要求用户正确地分配它(使用),并保证使用
其他方法只是。。。糟糕。如果您的用户有不同的编译器,那么即使他们使用了malloc
,您也不能free()
该字符串
[注:根据James的请求转换为评论,这实际上只是Windows特有的最后一个案例]
进一步说明:BSTR是Unicode。我记得有一种方法使用BSTR分配器来存储ANSI字符串,似乎<>代码> SysAllocStringByteLen <代码>,但是要警告,将ANSI数据放入BSTR对任何熟悉BSTR的人都是非常违反直觉的。 < >关于C++中内存分配的事情,智能指针是非常棒的。就这么说吧
最佳答案(IMHO):使用不透明的指针来保证struct
仅在库中创建。(如果我使用Windows,我会提供更多帮助。抱歉,不过+1。)谢谢,如果最坏的情况发生,我可以这样做,也可以使用SEH(尽管后者会让我觉得我做错了什么)。鉴于这是一个Windows库,请将此论点作为BSTR。然后,您需要用户正确地分配它(使用SysAllocString
),并保证使用匹配的deallocator。其他方法只是。。。糟糕。如果您的用户有不同的编译器,则您不能free()
字符串,即使他们确实使用了malloc
在我释放字符串之前,我将在字符串上使用(gasp)IsBadWritePtr的可能重复项。。。如果是字符串文字,它将返回true,我不会尝试释放字符串。我知道,但如果有人使用struct->val=“random”;然后我又遇到了一个问题,问题是在我编译的时候它不知道,只知道那些真正调用我的库的人。指针只是一个数字。@James这是关于所有权的。要问的问题是谁拥有指针。这是您在函数的文档中所说的。无论如何,调用方都不应该检查是否应该释放指针。同样,这是你需要弄清楚的静态信息。根据评论,这是一个很好的建议,除了(1)Windows上的库(2)和(3)显然是预编译的。并且std::string
被判定为在Windows上跨越模块边界是不安全的。按照Win32 API的模式,您给出的第一个项目符号是Windows库处理内存的首选方法。@Ben:Windows编程:不是我的强项(我想很有趣)。当然,您是对的:如果您不能控制库的构建过程以及与之相关的任何链接,那么这将是一个很大的问题。如果您将BSTR解决方案作为答案发布,我将向上投票。这是最合理的解决方案,依我看。谁的堆?在Windows上,每个库都倾向于获得自己不兼容的malloc/free堆。Win32 API函数HeapAlloc
和HeapFree
跨模块边界工作,但它们与CRT提供的malloc和free在任何模块中都不兼容。malloc()使用的堆,根据OP如何分配存储在堆上的字符串。好的,但我似乎记得有一些
char* s1 = "A String";
char* s2 = (char*)memcpy(malloc(9), s1, 9);
free(s2);
free(s1);