The POSIX putenv system call indicates that the allocated memory line cannot be freed by the caller after the putenv call. Therefore, you cannot call putenv with an automatic variable.
Example:
#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! }
My question is at this point ... how is the environment variable free 'd? Do I need to maintain them in a separate repository and constantly remove things from the environment? I.e.
#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! }
EDIT: it looks like I need to track this myself, at least according to Valgrind:
#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) */
c ++ unix system-calls
Billy oneal
source share