2

当我创建一个返回 char* 或 const char* 的函数时,是否假定调用函数在完成返回值后必须解除分配?否则,它将如何被释放?我正在寻找一些其他代码,它调用一个返回 char* 的函数,并且调用函数中没有删除语句。例子:

char* foo();

void bar()
{
    char* result = foo();
    //I should have "delete result" here right?
}

编辑:

所以在我的应用程序中是 foo:

LPTSTR GetTempPath(LPCTSTR fileName)
{   
    LPTSTR tempPath = new TCHAR[500];
    GetTempPath(500,tempPath);
    printf("Temp Path %ls\n",tempPath);
    PathAppend(tempPath, fileName);
    _tprintf(_T("New temp path: %s\n"), tempPath);
    return tempPath;
}

如果没有新的 TCHAR,我不确定如何写这个。我假设这必须删除?有没有更好的写法?

4

4 回答 4

6

如果你使用的是 C++ 而不是 C,你应该使用它std::string来解决这个问题。

于 2013-06-06T19:13:02.837 回答
4

char*当函数返回 a时,(至少)有两种常见约定。如果不阅读该函数的文档,您将无法判断哪个有效。

  1. 该函数返回一个指向静态分配内存的指针。在这种情况下,调用者不需要释放它。
  2. 该函数返回一个指向堆分配内存的指针。在这种情况下,调用者确实需要释放它。函数的文档必须指定调用者必须如何释放函数(释放、删除等)

现在,由于您负责编写自己的函数,因此您可以选择您喜欢的任何协议。在你的情况下,你不应该char*从你的函数中返回 a 。选择第三种方式。返回 astd::string并让标准库负责分配和释放。这样做是为了让图书馆的消费者生活更轻松。

事实上,既然你正在编写 C++,你应该回避char*. 当然,在与 Windows API 交互时必须使用 C 字符串。但就这样吧。不要将痛苦传递给图书馆的消费者。隐藏这种复杂性。

在你的情况下,我会确保你有一个可以组合两个std::string实例的函数。这也许可以使用 来实现PathAppend,但很容易自己动手。然后,您需要与 Windows API 进行的唯一交互是一个以字符串形式返回临时目录的函数。看起来像这样:

string GetTempDir()
{
    char buff[MAX_PATH+1];
    DWORD count = GetTempPath(MAX_PATH+1, buff); // I've omitted error checking
    return string(buff, count);
}

此函数中的代码是唯一需要处理 C 字符串的代码。您现在可以在其余代码中忘记它们,这可以将其视为黑匣子。不要让 Win32 的最低公分母 C 接口的实现细节泄漏到您精心分解的 C++ 代码中。

于 2013-06-06T19:26:12.367 回答
2

如果foo()在外部动态库中,库应该提供一些明确的方式来删除结果,如果需要删除,或者其他方式来关闭工作会话等等。

于 2013-06-06T19:21:03.720 回答
-1

要回答您提出的问题(“是否假定调用函数在完成返回值后必须释放它?否则,它将如何被释放?”):

不,调用者不一定要解除分配字符串。看着man ctime

char *ctime(const time_t *timep);

返回值指向一个静态分配的字符串,随后调用任何日期和时间函数可能会覆盖该字符串。

这意味着您不知道delete也不free知道它返回的字符串。

于 2013-06-06T19:42:30.343 回答