Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查是否可以释放指针_C++_Memory_Pointers_Free - Fatal编程技术网

C++ 检查是否可以释放指针

C++ 检查是否可以释放指针,c++,memory,pointers,free,C++,Memory,Pointers,Free,我到处寻找答案,但似乎找不到答案。(我在C++方面的经验相当有限) 在我的图书馆里,我释放了一个字符串。(太棒了,是吧?) 这就是问题所在。我有一个包含char*的结构,可以在堆上分配,也可以不分配。虽然它是一个有效指针,但无法释放它 即 将在“free(s1);”上导致错误(应如此) 因为s1实际上不需要释放(它不在堆上),所以我如何以“可接受”的方式处理它?(在类似的话题上,“让它崩溃”的答案在国际海事组织看来并不合理) 由于结构不是由库单独创建的,因此无法保证使用memcpy之类的东西正确

我到处寻找答案,但似乎找不到答案。(我在C++方面的经验相当有限)

在我的图书馆里,我释放了一个字符串。(太棒了,是吧?)

这就是问题所在。我有一个包含char*的结构,可以在堆上分配,也可以不分配。虽然它是一个有效指针,但无法释放它

将在“free(s1);”上导致错误(应如此) 因为s1实际上不需要释放(它不在堆上),所以我如何以“可接受”的方式处理它?(在类似的话题上,“让它崩溃”的答案在国际海事组织看来并不合理)

由于结构不是由库单独创建的,因此无法保证使用memcpy之类的东西正确复制字符串


因为这是一个Windows库,我不需要担心使用ISOC的东西或标准的C函数。C++中的

< P>,你根本不必担心这个。使用
std::string
并让它自动为您管理内存

如果要手动执行此操作,则需要通过

  • 让库的用户自己管理内存,或
  • 要求用户告诉您如何管理内存,或
  • 告诉用户您将如何管理内存,然后期望用户遵守

您可以malloc
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);