将环境变量存储在动态分配的数组中

Posted

技术标签:

【中文标题】将环境变量存储在动态分配的数组中【英文标题】:Storing environ variables in a dynamically allocated array 【发布时间】:2016-10-12 18:28:11 【问题描述】:

我目前正在研究一个存储字符串的类。它应该有两个独立的构造函数,一个允许用户使用 argv 类型的参数初始化对象,而另一个使用 environ 类型的参数初始化对象。

当我使用 argv 时一切正常,对象已正确初始化并存储了我在命令行中添加的每个字符串。 但是,对于环境变量,我遇到了麻烦。 将每个环境字符串存储到我的对象中似乎是雄心勃勃的,因为它超出了我可以访问的内存。

有什么方法可以减小环境变量的大小,或者控制 main 作为参数的变量的数量?

仅供参考,该类包含两个数据成员:一个存储存储的字符串数量,另一个是实际的字符串数组。 我尝试使用动态分配的数组,使用环境变量的数量作为参数(使用 for 循环计数)。但是,变量似乎太多,因此我最终会遇到 bad_alloc 错误。

Stringstore::Stringstore(char ** envp)
  
    for (char** env = envp; *envp != nullptr; ++env)
        ++d_size;
    d_str = new string[d_size];
    for (int index=0; index != d_size; ++index)
        d_str[index] = envp[index];
 

class Stringstore

string *d_str;
int d_size;
public:
    Stringstore(int argc, char **argv1);
    Stringstore(char **envp);
;


int main(int argc, char **argv, char **envp)

    Stringstore(envp);    

【问题讨论】:

也许你可以发布一些minimal reproducible example ?在现代计算机上,我很惊讶您无法复制某些环境。变量。 我已经添加了我目前必须使用环境变量初始化对象的核心代码。 错误的症状是什么,会不会是无限循环? (并假设内存错误是错误的) 实际上,当我尝试使用计算出的大小动态分配数组时,就会出现错误。每当我要求用户输入要存储的环境变量的数量时,程序执行得很好。也许我目前的内存无法存储每个环境变量。 【参考方案1】:

这个循环用来计算有多少 env。您收到的 vars 是一个无限循环。 envp 不会从一次迭代更改为另一次迭代。

for (char** env = envp; *envp != nullptr; ++env)
        ++d_size;

由于一开始envp 不是nullptr,所以你永远不会达到退出条件,这让你相信你的内存已经用完了,但不是:你的 CPU 用完了:)

另一个错误:主要是你应该构建一个对象而不是尝试“转换”到Stringstore

int main(int argc, char **argv, char **envp)

    Stringstore the_string_store(envp);    

请注意,使用向量(自动重新分配,没有 new,类的简单复制构造函数)可能会避免该错误。让我提出一个固定的代码(最终打印 env 以证明它有效)

#include <string>
#include <vector>
#include <iostream>

using namespace std;

class Stringstore

std::vector<string> d_str;
public:
    Stringstore(int argc, char **argv1);
    Stringstore(char **envp);
;
Stringstore::Stringstore(char ** envp)
  
    // store each env. string
    for (; *envp != nullptr; ++envp)
        d_str.push_back(*envp);

   // debug: print the contents of the vector
   for (auto it : d_str)
   
      cout << it << endl;
   
 


int main(int argc, char **argv, char **envp)

    Stringstore s(envp);    

运行这个我得到这个:

ALLUSERSPROFILE=C:\ProgramData
APPDATA=D:\Users\xxxxxxx\AppData\Roaming
CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=xxxxxx
...

最后一次编辑:如果您不允许使用 vector,那就太糟糕了,但是您的方法的这个固定版本可以正常工作:

Stringstore::Stringstore(char ** envp)
  
    // make a copy so we can count and preserve the original pointer
    // for the second pass: the string copy
    char **envp_copy = envp;  
    d_size = 0;  // you forgot to initialize it too :)

    for (; *envp_copy != nullptr; ++envp_copy)
        d_size++;  // count

    // the rest is your code, unchanged
    d_str = new string[d_size];
    for (int index=0; index != d_size; ++index)
        d_str[index] = envp[index];

    // debug: print env
    for (int index=0; index != d_size; ++index)
    
        cout << d_str[index] << endl;
    


【讨论】:

感谢您的回复! 感谢您的回复! cast 实际上是一种类型。对于将所有环境字符串存储在数组中,您还有其他建议吗? 首先,我感谢您的努力!但是,我的课程清楚地表明我不应该使用讲座尚未涵盖的任何工具。可悲的是,我目前还不能使用矢量。但是,我会为任何未来的程序记住这个解决方案。您是否碰巧知道我提供的类的解决方案(即使用 d_str 数组)。我不允许添加任何其他数据成员或修改这些。 没问题,看我的编辑,只是不是“真正的”C++。它是什么教学法?你不能使用vector,所以你可能会因为使用string而受到惩罚。两者现在都是 C++ 库的一部分。告诉你的老师“来吧,现在是 2016 年”。 完美,非常感谢!为什么我们需要复制来计算元素的数量?我猜每个老师都有自己的风格;)

以上是关于将环境变量存储在动态分配的数组中的主要内容,如果未能解决你的问题,请参考以下文章

数组的引用变量和内存分配

指向动态二维字符数组的三重指针的内存分配

变量的存储空间分配情况

动态内存分配与指向它的指针变量

环境变量

初始typescript及vscode环境配置