Хранение переменных окружения в динамически распределенном массиве

В настоящее время я работаю над классом, который хранит строки. Предполагается, что он имеет два отдельных конструктора, один из которых позволяет пользователю инициализировать объект с аргументами типа argv, а другой инициализирует объект с аргументами типа окружающей среды.

Все отлично работает, когда я использую 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);
}

0

Решение

Этот цикл вы используете, чтобы посчитать, сколько env. Вары, которые вы получаете, представляют собой бесконечный цикл. envp не изменяется от одной итерации к другой.

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

поскольку envp не является nullptr в начале вы никогда не достигнете условия выхода, которое заставляет вас верить, что у вас заканчивается память, но нет: у вас не хватает процессора 🙂

Еще одна ошибка: в основном вы должны построить объект, а не пытаться «привести» к 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;
}

}
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector