0

我目前正在研究一个存储字符串的类。它应该有两个单独的构造函数,一个允许用户使用 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);    
}
4

1 回答 1

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);    
}

请注意,使用向量(auto-realloc,no 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;
    }

}
于 2016-10-12T19:10:08.410 回答