- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我一直在思考环境变量,并有一些问题/意见。
putenv(char *string);
这个调用似乎有致命的缺陷。因为它不复制传递的字符串,所以你不能用本地调用它,并且不能保证堆分配的字符串不会被覆盖或意外删除。此外(虽然我没有测试过),因为环境变量的一种用途是将值传递给 child 的环境,如果 child 调用 exec*()
函数之一,这似乎没用。我错了吗?
Linux 手册页表明 glibc 2.0-2.1.1 放弃了上述行为并开始复制字符串,但这导致了内存泄漏,已在 glibc 2.1.2 中修复。我不清楚这个内存泄漏是什么或如何修复的。
setenv()
复制字符串,但我不知道它是如何工作的。进程加载时为环境分配空间,但它是固定的。这里有一些(任意的?)约定吗?例如,在 env 字符串指针数组中分配比当前使用更多的插槽,并根据需要向下移动空终止指针?新的(复制的)字符串的内存是否分配在环境本身的地址空间中,如果它太大而无法容纳您只需获得 ENOMEM?
考虑到上述问题,有什么理由更喜欢 putenv()
而不是 setenv()
?
最佳答案
- [The]
putenv(char *string);
[...] call seems fatally flawed.
是的,它有致命的缺陷。 它被保存在 POSIX (1988) 中,因为那是现有技术。 更正: POSIX 1990 标准在 §B.4.6.1 中说“附加函数 putenv() 和 clearenv() 被考虑但被拒绝”。 Single Unix Specification (SUS) 1997 年的第 2 版列出了 setenv()
机制稍后出现。putenv()
,但没有列出 setenv()
或 unsetenv()
。下一个版本 (2004) 确实定义了 setenv()
和 unsetenv()
也是。
Because it doesn't copy the passed string you can't call it with a local and there is no guarantee a heap allocated string won't be overwritten or accidentally deleted.
你说得对,将局部变量传递给 putenv()
几乎总是一个糟糕的选择——异常模糊到几乎不存在的地步。如果字符串是在堆上分配的(使用 malloc()
等),您必须确保您的代码不会修改它。如果是,则同时在修改环境。
Furthermore (though I haven't tested it), since one use of environment variables is to pass values to child's environment this seems useless if the child calls one of the
exec*()
functions. Am I wrong in that?
exec*()
函数制作环境的副本并将其传递给执行的进程。那里没有问题。
The Linux man page indicates that glibc 2.0-2.1.1 abandoned the above behavior and began copying the string but this led to a memory leak that was fixed in glibc 2.1.2. It's not clear to me what this memory leak was or how it was fixed.
内存泄漏的出现是因为一旦你用一个字符串调用了 putenv()
,你就不能再出于任何目的使用该字符串,因为你无法判断它是否仍在使用,尽管你可以通过覆盖来修改值(如果将名称更改为在环境中另一个位置找到的环境变量的名称,则结果不确定)。所以,如果你已经分配了空间,经典的 putenv()
如果你再次更改变量就会泄漏它。当 putenv()
开始复制数据时,分配的变量变为未引用,因为 putenv()
不再保留对参数的引用,但用户期望环境将引用它,所以内存被泄露了。我不确定修复是什么——我 3/4 预计它会恢复到旧的行为。
setenv()
copies the string but I don't know exactly how that works. Space for the environment is allocated when the process loads but it is fixed.
原来的环境空间是固定的;当你开始修改它时,规则就会改变。即使使用 putenv()
,原始环境也会被修改,并且可能会因添加新变量或将现有变量更改为更长的值而增长。
Is there some (arbitrary?) convention at work here? For example, allocating more slots in the env string pointer array than currently used and moving the null terminating pointer down as needed?
这就是 setenv()
机制可能会做的事情。 (全局)变量 environ
指向环境变量指针数组的开头。如果它一次指向一个内存块,另一个时间指向另一个 block ,那么环境就被切换了,就这样。
Is the memory for the new (copied) string allocated in the address space of the environment itself and if it is too big to fit you just get ENOMEM?
嗯,是的,您可以获得 ENOMEM,但您必须非常努力。如果你将环境扩展得太大,你可能无法正确执行其他程序——要么环境被截断,要么执行操作失败。
Considering the above issues, is there any reason to prefer putenv() over setenv()?
setenv()
。setenv()
,但不要将其作为首要任务。putenv()
。关于c - 关于 putenv() 和 setenv() 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5873029/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!