Производительность и безопасность локального массива в качестве параметра - PullRequest
0 голосов
/ 08 июля 2011

Я просто хочу убедиться, что с этим нет никаких потенциальных проблем. Он компилируется и работает нормально, но рискую ли я какими-нибудь странными эффектами памяти? Должен ли я быть особенно обеспокоен исключениями в этом случае?

//...constructor of some class
myobj(int length, int *vars)
{
    // do stuff with vars
}

// inside some other code somewhere
int vars[3] = {5,6,7};
myobj *o = new myobj(3,vars);

(Правка.) Я просто обеспокоен, потому что знаю, что указатели на объекты в стеке всегда следует использовать с осторожностью. Если говорить конкретно о моем использовании, я бы в основном хотел получить самый быстрый способ передать переменное число аргументов одного типа. Так это плохой способ сделать это? Спасибо ..

Postscript. Все ответы были очень полезны, спасибо! Я посмотрю, достаточно ли важна производительность, чтобы использовать этот метод, или, возможно, смогу ли я решить проблему другим способом.

Ответы [ 3 ]

1 голос
/ 08 июля 2011

Если ваш класс myobj по какой-то причине хранит указатель на int[], тогда вы открываете двери для всех видов неприятностей - когда исходный массив vars выходит из области видимости, вы остаетесь с свисающий указатель; Вы не можете легко скопировать свой класс; Вы должны думать о безопасности исключений; и т. д.

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

Ссылаясь на заголовок вашего вопроса, если вы действительно просто передаете массив "некоторой свободной функции", то, возможно, это может быть оправдано, но вы явно говорите, что используете его в конструкторе динамически размещаемого объекта. Это просто пахнет неприятностями.

1 голос
/ 08 июля 2011

В этом нет ничего по своей сути .Однако есть несколько вещей, с которыми вам нужно быть осторожными:

  • Не держите указатель на vars после того, как вы вернетесь (или, по крайней мере, после того, как он выйдет из области видимости).vars действует только до тех пор, пока вы не покинете область, в которой он был объявлен.
  • Убедитесь, что вы не выходите за пределы конца vars массива.

Этоболее распространенный стиль в C ++ для использования, например, параметр std::vector<int> & или другой тип контейнера.Для этого есть две основные причины: передача в качестве ссылки делает более очевидным, что вы не должны хранить указатель на объект, а передача вектора позволяет сохранить размер массива вместе с массивом.сам (и вы можете расширить массив, если это будет необходимо).Однако это вопрос стиля и накладных расходов на vector, поэтому, если производительность выше, такой подход вполне разумен.

1 голос
/ 08 июля 2011

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

Это не очень хороший C ++ - что не так с использованием const vector<int>& в качестве параметра?

В частности, не храните указатель на ваш основанный на стеке массив в экземпляре myobj, который создан из него - т.е. вам нужно скопировать входные int значения в класс, если вы не используете что-то вроде boost :: shared_array .

...