Возврат двумерного массива двойников из функции - PullRequest
1 голос
/ 30 марта 2009

У меня есть этот класс, в котором в какой-то момент я вычисляю массив из двух двойных чисел:

double* QSweep::computeIntersection(double m1, double b1, double m2, double b2){
double* v=new double[2];

v[0]= (b2-b1)/(m1-m2);
v[1]= (m1*b2-m2*b1)/(m1-m2);

return v;
}

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

спасибо заранее, Madalina

Ответы [ 7 ]

9 голосов
/ 30 марта 2009

Если они всегда являются двумя значениями, не будет ли более логичным (и более полезным) вернуть std::pair<double, double>? Это может избавить от многих проблем, особенно связанных с явным управлением памятью (поскольку вы используете new / delete):

std::pair<double, double> QSweep::computeIntersection(
    double m1, double b1, double m2, double b2
) {
    return std::make_pair( (b2-b1)/(m1-m2), (m1*b2-m2*b1)/(m1-m2));
}
2 голосов
/ 30 марта 2009

Другой вариант - изменить подпись:

void QSweep::computeIntersection(double m1, double b1, double m2, double b2, double& return_v0, double& return_v1)
{
    return_v0 = (b2-b1)/(m1-m2);
    return_v1 = (m1*b2-m2*b1)/(m1-m2);
}
1 голос
/ 30 марта 2009

В вашем примере недостаточно информации, чтобы ответить на ваш вопрос о причине сбоя.

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

typedef std::pair<double, double> Intersection;
typedef std::vector<Intersection> Plane;

Intersection QSweep::computeIntersection
  ( double m1
  , double b1
  , double m2
  , double b2) 
{
    return Intersection( (b2-b1)/(m1-m2), (m1*b2-m2*b1)/(m1-m2));
}

main() 
{
  Plane plane;
  while( input ){
    plane.push_back( Intersection( ... ) );
  }
}

Могут быть и другие способы хранения этого, например, если вы используете double, вы можете использовать calloc и realloc, чтобы поддерживать один фрагмент памяти нужного размера. (пока не рекомендую, учитывая ваш пример)

1 голос
/ 30 марта 2009

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

typedef std::pair<double, double> Intersection

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

В любом случае вам лучше вернуть эти значения по значению, чем возвращать указатель на выделенную кучу память.

0 голосов
/ 31 марта 2009

спасибо :), он работал с push_back значением, полученным каждый раз в новом векторе типа

vector <double *>,

Madalina

0 голосов
/ 30 марта 2009

Учитывая, что у вас есть массив из двух двойных чисел, я не сомневаюсь, что есть необходимость увеличить это число в какое-то время. Мол, если в какой-то момент вы тоже решите добавить 3d-функции. Я бы поэтому предпочел остаться с массивом. Но нет необходимости использовать динамический массив. Используйте массив, завернутый в структуру, такую ​​как boost::array:

boost::array<double, 2> QSweep::computeIntersection(
    double m1, double b1, double m2, double b2
) {
    boost::array<double, 2> array = { (b2-b1)/(m1-m2),  (m1*b2-m2*b1)/(m1-m2) };
    return array;
}

Затем вы можете добавить его к вектору, который будет содержать:

typedef std::vector< boost::array<double, 2> > vec_of_2darray_t;
vec_of_2darray_t v;
v.push_back(computeIntersection(a, b, c, d));
// ...

Это, вероятно, лучшее, что вы можете получить, если стремитесь к простоте и расширяемости. boost::array - довольно маленькая и простая структура. Это в основном составляет

template<typename T, size_t N>
struct array { T data[N]; };

И, конечно, несколько функций, таких как operator[], begin(), end() и другие. Но без конструкторов, чтобы вы могли инициализировать его как обычный массив, как мы делали выше.

0 голосов
/ 30 марта 2009

Используйте vector, чтобы сохранить историю двойников. Если вы продолжаете использовать массив пар, чтобы удержать их, сделайте что-то вроде этого:

std::vector<double*> history;
history.push_back(v);

Обратите внимание, вам все равно потребуется delete память, на которую указывает каждый элемент, когда вы закончите работу с вектором (или отдельными элементами вектора). Чтобы обойти это, используйте pair для отслеживания вашего исходного массива двойных чисел (если вы используете только два) или vector<double>.

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