C ++语言具有有关如何释放指针所指向的内存的特定规则。这些规则要求您知道如何分配内存以便正确释放它。
例如,
int *p = new int();
std::free(p);
导致未定义的行为。 (Reference)
在现代C ++中,我们希望在可能的情况下使用智能指针,但有时我们可能希望使用分配原始指针的库或函数。假设我要使用以下形式的函数:
char* NotMyFunction();
如何正确管理此功能分配的内存?
答案 0 :(得分:8)
如何正确管理此功能分配的内存?
您首先阅读了该函数的文档,然后执行该文档告诉您的操作以及何时执行该操作,假设首先要做的事情是。重要的是要记住,并非所有的指针都指向动态内存。
示例:strdup
的说明为:
返回一个以空值结尾的字节字符串的指针,该字符串是str1指向的字符串的副本。 返回的指针必须传递到
free
,以避免内存泄漏。
如果没有可用的文档,则可以阅读源代码以查看函数的作用并采取相应的措施。如果来源也不可用,那么您就麻烦了,可能需要投资购买水晶球。
不包括标准函数,获取诸如动态内存之类的资源并返回句柄(在动态内存的情况下为指针)的C API通常提供相应的函数来释放资源。例如:SDL_CreateWindow
和SDL_DestroyWindow
。
我推断您在说以下内容是否正确?通常,如果为您提供了C ++中的原始指针,则不可能保证该指针的正确内存管理。
您的意思不清楚。如果您知道如何管理内存,则可以正确进行。如果您不知道如何管理内存(或者根本不需要管理内存),那么您需要一种找到知识的方法。在C ++中,没有一种合理的方式来编写程序(通过自省)来确定应如何以及何时释放内存。
类型char*
本身并没有说明应如何处理内存。甚至指针的值也不会告诉您任何东西,如果它为null,那么它就不会指向对象。如果指针非空,则它可能指向一个对象。
答案 1 :(得分:0)
int *p = new int();
std::free(p);
那是不正确的,应该是:
int *p = new int;
delete p;
或
int *p = (int*) malloc(sizeof(int));
free(p);
关于char* NotMyFunction();
,无论您在何处分配char *,请不要忘记释放或删除它。不要松开指针,将需要它来释放内存。
char *NotMyFunction()
{
char* s = new char[n];
...
return s;
}
稍后:
char* nmf = NotMyFunction();
...
delete[] mfc;
答案 2 :(得分:0)
我没有足够的C ++知识对自己说,但是根据user2079303在他们的answer中写的内容,似乎该问题的理论答案是这是不可能的< / strong>。但是,实际上有很多方法可以解决此问题。
1。查看文档
在大多数情况下,如果您要开发使用库的软件,则应具有提供此信息的文档。如果不是,您可能会想知道使用此库的好处是否真的超过了成本。
2。检查源代码
如果您可以访问源代码,则应该能够找到有关内存的分配方式。这很可能比选项 1 更困难,但是它为您提供了明确的答案,而不是别人写的答案(应该是正确的,但实际上不是)不必)。
3。使用valgrind
Valgrind是调试实用工具,不是证明正确性的工具(如果我错了,请纠正我),但是在没有直接访问资源的情况下,我们需要回答这个问题,它可能非常有用。我们可以尝试以下程序,在该程序中,我们设想在我们的应用程序中可能无法访问MysteryFunctionOne
和MysteryFunctionTwo
的主体:
#include <iostream>
int* MysteryFunctionOne() {
return new int();
}
int* MysteryFunctionTwo() {
return (int *) malloc(sizeof(int));
}
int main() {
int* p1 = MysteryFunctionOne();
int* p2 = MysteryFunctionTwo();
std::cout << std::hex << p1 << std::endl << p2 << std::endl;
// For illustrative purposes, suppose we free both pointers incorrectly
free(p1);
delete p2;
return 0;
}
如果我们使用valgrind program_name
编译并运行上述程序,则会收到两条重要的错误消息,其中一条是:
Mismatched free() / delete / delete []
at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x400A2E: main (in <path/to/program>)
Address 0x5ab6c80 is 0 bytes inside a block of size 4 alloc'd
at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x4009A3: MysteryFunctionOne() (in <path/to/program>)
by 0x4009C8: main (in <path/to/program>)
这告诉我们我们在函数free
中错误地使用了main
。错误消息的下半部分甚至使我们知道operator new
中使用了MysteryFunctionOne()
。因此我们知道我们需要delete
返回的指针MysteryFunctionOne()
,所以我们进行了更改
free(p1);
到
delete p1;
我们收到的第二条错误消息是类似的,从中我们得知我们需要free(p2)
。
在这种情况下,即使不阅读源代码或文档,valgrind仍然可以指导我们进行正确的内存管理。通常,情况并非总是如此,但是在没有源代码或重要文档的情况下,可以考虑使用此选项。