создать глобальный динамический массив внутри функции - PullRequest
1 голос
/ 19 июня 2011

Я пишу программу на C ++.В моей программе мне нужно создать массив с динамическим размером внутри одной функции, но этот массив должен быть доступен и для других функций.Я не буду публиковать здесь свой код, просто напишу один фиктивный пример.

char *array;


void function_1() {
    array = new char(3);
    array[0] = "value 1";
    array[1] = "value 2";
    array[2] = "value 3";
}

void function_2() {
    array[0] = "new value 1";
}

int main() {
    function_1();
    function_2();

    delete[] array;
}

Мой вопрос: я не уверен, будет ли массив существовать за пределами function_1, где он был инициализирован, до тех пор, пока я не удалюпамять массива.Или массив будет иметь поведение локальной переменной внутри одной функции.Что означает, что память, в которой хранятся значения массива, будет выделена после завершения функции, а адреса памяти моего массива могут быть переписаны с чем-то другим позже в моей программе.

Спасибо.

Ответы [ 6 ]

7 голосов
/ 19 июня 2011

Во-первых, конечно, он будет существовать снаружи, вот и все, что такое динамическое распределение. Кроме того, сама переменная является глобальной. Кроме того, это должно быть char const** array;, а распределение должно быть new char const*[3] (обратите внимание на квадратные скобки). const, потому что здесь вы не измените содержимое строк.

Во-вторых, не делайте этого . Просто поместите это в класс и используйте std::vector!

#include <vector>

class Foo{
public:
  function_1(){
    _array.push_back("value 1");
    _array.push_back("value 2");
    _array.push_back("value 3");
  }

  function_2(){
    _array[0] = ("new value 1");
  }

private:
  std::vector<std::string> _array;
};

int main(){
  Foo f;
  f.function_1();
  f.function_2();
}

Еще лучше иметь std::vector<std::string>, чтобы вы могли безопасно изменять содержимое, не беспокоясь об управлении памятью. Впрочем, до этого уже не будет ни одного блока. Теперь я должен спросить, как именно вы хотите передать буфер в сокет?

3 голосов
/ 19 июня 2011

У вас действительно есть фатальная ошибка в вашей функции_1 ().Следующий код заставит массив указывать на символ со значением 3. Затем он будет перезаписывать различные части соседней памяти, в основном вызывая переполнение буфера.

void function_1() {
    array = new char(3);
    array[0] = "value 1";
    array[1] = "value 2";
    array[2] = "value 3";
}

Что вы, вероятно, хотите сделать, этосоздать что-то вроде:

char **array;
array = new char*[3];
array[0] = new char[strlen(...)];
array[0] = strncpy(array[0], ..., strlen(...)];
// etc

Гораздо более безопасный и понятный способ сделать это - сделать то, что предлагает Xeo, и использовать std :: vector вместо простого массива.

2 голосов
/ 19 июня 2011

Это значительно улучшило бы ясность вашего кода, если бы вы:

  • использовали std :: vector, особенно если вы планируете изменить его размер позже
  • используйте std:: string для представления строк
  • передать массив или вектор по ссылке на функции, которые в нем нуждаются.

    int main() {
    std::vector<std::string> vect;
    
    function_1(vect);
    function_2(vect);
    }
    

, где ваши функции выглядят так:

void function_1(std::vector<std::string> & Vect) 

typedefs помогает управлять типами аргументов

Таким образом, вам не придется беспокоиться о утечках, так как вектор будет освобожден, когда выйдет из области видимости.

2 голосов
/ 19 июня 2011

Память, которую вы выделяете в функции 1, останется выделенной после того, как программа выйдет из области действия функции, и будет работать, как ожидается, в функциях 2 и 3. Обратите внимание, что поведение не определено, если вы вызываете функции 2 и 3 перед первой функцией , В общем, то, что вы пытаетесь сделать здесь, выглядит как плохой дизайн, но ради вопроса, я не буду вас об этом сейчас беспокоить:)

2 голосов
/ 19 июня 2011

Он будет существовать и будет глобальным, потому что указатель char * array является глобальным.

2 голосов
/ 19 июня 2011

Поскольку array является глобальным, он виден другим функциям.Память, выделенная с помощью new[], остается до тех пор, пока она не будет освобождена с помощью delete[].

...