【发布时间】:2011-06-14 06:09:04
【问题描述】:
POSIX 系统调用putenv 表明调用者在调用putenv 后无法释放分配的内存字符串。因此,您不能使用自动变量调用putenv。
例子:
#include <cstdlib>
#include <cstring>
#include <unistd.h>
int main()
{
char envVar[] = "MYVAR=Value";
// putenv(envVar); //ERROR!
char *memory = static_cast<char*>(std::malloc(sizeof(envVar)));
std::strcpy(memory, envVar);
putenv(memory); //OK!
}
此时我的问题是……环境变量内存free'd 怎么样?是否需要将它们保存在单独的存储中并不断从环境中移除东西?即
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
static std::map<std::string, char*> environmentBlock;
static struct EnvironmentBlockFreer
{
~EnvironmentBlockFreer()
{
for(std::map<std::string, char*>::iterator it = environmentBlock.begin()
it != environmentBlock.end(); ++it)
{
putenv(it->first.c_str()); //Remove entry from the environment
std::free(static_cast<void *>(it->second)); //Nuke the memory
}
}
} EnvironmentBlockFreer_ENTRY;
int main()
{
char envVar[] = "MYVAR=Value";
char *memory = static_cast<char*>(std::malloc(sizeof(envVar)));
std::strcpy(memory, envVar);
putenv(memory); //OK!
environmentBlock.insert(std::pair<std::string, char*>(
"MYVAR", memory)); //Remember the values for later!
}
编辑:看起来我需要自己跟踪这个,至少根据 Valgrind 的说法:
/* This program: */
#include <stdlib.h>
#include <string.h>
int main()
{
char str[] = "MYVAR=Example";
char *mem = malloc(sizeof(str));
strcpy(mem, str);
putenv(mem);
}
/* Produced output:
==4219== Memcheck, a memory error detector
==4219== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4219== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==4219== Command: ./a.out
==4219==
==4219==
==4219== HEAP SUMMARY:
==4219== in use at exit: 14 bytes in 1 blocks
==4219== total heap usage: 2 allocs, 1 frees, 194 bytes allocated
==4219==
==4219== LEAK SUMMARY:
==4219== definitely lost: 14 bytes in 1 blocks
==4219== indirectly lost: 0 bytes in 0 blocks
==4219== possibly lost: 0 bytes in 0 blocks
==4219== still reachable: 0 bytes in 0 blocks
==4219== suppressed: 0 bytes in 0 blocks
==4219== Rerun with --leak-check=full to see details of leaked memory
==4219==
==4219== For counts of detected and suppressed errors, rerun with: -v
==4219== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 8)
*/
【问题讨论】:
-
我不会打扰 malloc/free,将字符串存储在您的地图中并将它们的 c_str 传递给 putenv。只要不需要putenv的荒谬特性,可以通过写入字符串来修改环境,就是……
-
@Steve -- 这些只是我在 5 分钟内完成的垃圾测试......不是真正的代码 :) 如果
putenv实际上在内存块上调用了free,我不想造成问题所以我使用了malloc。 -
在这种情况下,我会说,“是的,但是看在上帝的份上,通过使用更好的 C++ 接口来复制用户提供的字符串来包围 putenv”。
标签: c++ unix system-calls