8
int main(int argc, char *argv[])
{
    char *ret = setlocale(LC_ALL, NULL);
    // should I free 'ret' ???
    // free(ret);
    return 0;
}

我在 Linux 和 OS X 10.10 上都试过了,在 Linux 上,我不能调用“free”,但在 OS X 上,如果我不调用“free”,valgrind 会抱怨内存泄漏。

==62032== Memcheck, a memory error detector
==62032== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==62032== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==62032== Command: ./a.out
==62032== 
--62032-- ./a.out:
--62032-- dSYM directory is missing; consider using --dsymutil=yes
==62032== 
==62032== HEAP SUMMARY:
==62032==     in use at exit: 129,789 bytes in 436 blocks
==62032==   total heap usage: 519 allocs, 83 frees, 147,421 bytes allocated
==62032== 
==62032== 231 bytes in 1 blocks are definitely lost in loss record 63 of 91
==62032==    at 0x10000859B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==62032==    by 0x1001E68C8: currentlocale (in /usr/lib/system/libsystem_c.dylib)
==62032==    by 0x100000F6B: main (in ./a.out)
==62032== 
==62032== LEAK SUMMARY:
==62032==    definitely lost: 231 bytes in 1 blocks
==62032==    indirectly lost: 0 bytes in 0 blocks
==62032==      possibly lost: 0 bytes in 0 blocks
==62032==    still reachable: 94,869 bytes in 10 blocks
==62032==         suppressed: 34,689 bytes in 425 blocks
==62032== Reachable blocks (those to which a pointer was found) are not shown.
==62032== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==62032== 
==62032== For counts of detected and suppressed errors, rerun with: -v
==62032== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 17)

因此,在 Linux 中,如果我调用“免费”,它就会崩溃。在 OS X 中,如果我不调用“免费”,它就会发生内存泄漏。

4

1 回答 1

10

你不应该得到 free你得到的字符串。根据C11标准:

7.11.1.1setlocale功能

函数返回的指向字符串的指针 setlocale 使得随后使用该字符串值及其相关类别的调用将恢复程序区域设置的该部分。指向的字符串不应被程序修改,但可能会被随后的 setlocale 函数调用覆盖

此外,Linux手册页说:

该字符串可以分配在静态存储中。

如果您尝试这样做,这将导致您的程序崩溃free

看起来 Linux 实现使用静态存储,但 OSX 使用malloc. 不管幕后发生了什么,你都不应该修改它,因为标准不允许你这样做——它在 OSX 上是安全的这一事实是你应该忽略的一个实现怪癖。Valgrind 本质上是在这里给你一个误报。

于 2015-03-18T07:37:26.507 回答