Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
main(int argc, char *argv[], char *envp[])

Wiki MarkupHowever, modifying the environment by using the {{setenv()}} or {{putenv()}} functions, or by any other means , may cause the environment memory to be reallocated, with the result that {{envp}} now references an incorrect location.

For example, POSIX says the following: \[[Open Group 04|AA. C References#Open Group 04]\]

Unanticipated results may occur if setenv() changes the external variable environ.  In particular, if the optional envp argument to main() is present, it is not changed, and as a result may point to an obsolete copy of the environment (as may any other copy of environ).

Wiki Markup
Microsoft notes the following about {{getenv()}}: \[[MSDN|AA. C References#MSDN]\]

getenv and _putenv use the copy of the environment pointed to by the global variable _environ to access the environment. getenv operates only on the data structures accessible to the runtime library and not on the environment "segment" created for the process by the operating system. Consequently, programs that use the envp argument to main or wmain may retrieve invalid information.

Wiki Markup
The Visual C++ reference notes the following about {{envp}} \[[MSDN|AA. C References#MSDN]\]

The environment block passed to main and wmain is a "frozen" copy of the current environment. If you subsequently change the environment via a call to putenv or _wputenv, the current environment (as returned by getenv/_wgetenv and the _environ/ _wenviron variable) will change, but the block pointed to by envp will not change.

When example, when compiled with GCC version 3.4.6 and run on a 32-bit Intel GNU/Linux machine, the following code:

...

Non-Compliant Code Example (POSIX)

Wiki Markup
After a call to the POSIX {{setenv()}} function, or other function that modifies the environment, the {{envp}} pointer may no longer reference the environment.  POSIX states that \[[Open Group 04|AA. C References#Open Group 04]\]

Unanticipated results may occur if setenv() changes the external variable environ. In particular, if the optional envp argument to main() is present, it is not changed, and as a result may point to an obsolete copy of the environment (as may any other copy of environ).

Code Block
bgColor#ffcccc
int main(int argc, char const *argv[], char const *envp[]) {
   size_t i;
   if (setenv("MY_NEW_VAR", "new_value", 1) != 0) {
     /* Handle Error */
   }
   if (envp != NULL) {
      for (i = 0; envp[i] != NULL; i++) {
         puts(envp[i]);
      }
   }
   return 0;
}

...

After a call to the Windows _putenv_s() function, or other function that modifies the environment, the envp pointer may no longer reference the environment.

Wiki Markup
According to the Visual C++ reference \[[MSDN|AA. C References#MSDN]\]

The environment block passed to main and wmain is a "frozen" copy of the current environment. If you subsequently change the environment via a call to putenv or _wputenv, the current environment (as returned by getenv / _wgetenv and the _environ / _wenviron variable) will change, but the block pointed to by envp will not change.

Code Block
bgColor#ffcccc
int main(int argc, char const *argv[], char const *envp[]) {
   size_t i;
   if (_putenv_s("MY_NEW_VAR", "new_value", 1) != 0) {
     /* Handle Error */
   }
   if (envp != NULL) {
      for (i = 0; envp[i] != NULL; i++) {
         puts(envp[i]);
      }
   }
   return 0;
}

...