删除或释放

时间:2018-09-12 20:34:00

标签: c++

C ++语言具有有关如何释放指针所指向的内存的特定规则。这些规则要求您知道如何分配内存以便正确释放它。

例如,

int *p = new int();
std::free(p);

导致未定义的行为。 (Reference

在现代C ++中,我们希望在可能的情况下使用智能指针,但有时我们可能希望使用分配原始指针的库或函数。假设我要使用以下形式的函数:

char* NotMyFunction();

如何正确管理此功能分配的内存?

3 个答案:

答案 0 :(得分:8)

  

如何正确管理此功能分配的内存?

您首先阅读了该函数的文档,然后执行该文档告诉您的操作以及何时执行该操作,假设首先要做的事情是。重要的是要记住,并非所有的指针都指向动态内存。

示例:strdup的说明为:

  

返回一个以空值结尾的字节字符串的指针,该字符串是str1指向的字符串的副本。 返回的指针必须传递到free,以避免内存泄漏。

如果没有可用的文档,则可以阅读源代码以查看函数的作用并采取相应的措施。如果来源也不可用,那么您就麻烦了,可能需要投资购买水晶球。

不包括标准函数,获取诸如动态内存之类的资源并返回句柄(在动态内存的情况下为指针)的C API通常提供相应的函数来释放资源。例如:SDL_CreateWindowSDL_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是调试实用工具,不是证明正确性的工具(如果我错了,请纠正我),但是在没有直接访问资源的情况下,我们需要回答这个问题,它可能非常有用。我们可以尝试以下程序,在该程序中,我们设想在我们的应用程序中可能无法访问MysteryFunctionOneMysteryFunctionTwo的主体:

#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仍然可以指导我们进行正确的内存管理。通常,情况并非总是如此,但是在没有源代码或重要文档的情况下,可以考虑使用此选项。