освобождение gsl векторов в структурах - PullRequest
1 голос
/ 03 декабря 2010

Можете ли вы объяснить, что происходит с моим кодом здесь?Я не уверен, правильно ли я использую деструктор в структуре.

С деструктором там я получаю:
function1: 23
function2: 8.86183e-317
* Обнаружен glibc ./a: двойное освобождение или повреждение (fasttop): 0x000000000111b010 **

Если я просто закомментирую деструктор, я получу:
function1: 23
function2: 24

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

(Как вы можете заметить, я, возможно, немного запутался в отношении указателей / выделения)

Спасибо!

Редактировать: о да, и почему дополнительный шаг выделения в function1 имеет значение?

Edit2: я должен инициализировать x = 0 в конструкторе?Я подумал, что это правильно ... я должен выделить его на инициализацию, когда я делаю это?Так что вместо этого: x = gsl_vector_alloc (1).

#include <iostream>
    using namespace std;
#include <cassert>
#include <cmath>
#include <gsl/gsl_vector.h>

struct struct1{
    gsl_vector * x;

    struct1() {
        x = 0;
    }
    ~struct1() {
        if (x) gsl_vector_free(x);
    }
};

void function1(void *p) {
    struct1 s = *(struct1 *) p;
    s.x = gsl_vector_alloc(1);
    gsl_vector_set(s.x, 0, 24);
}

void function2(void *p) {
    struct1 s = *(struct1 *) p;
    gsl_vector_set(s.x, 0, 24);
}

int main() {
    struct1 s;
    s.x = gsl_vector_alloc(1);
    gsl_vector_set(s.x, 0, 23);

    function1(&s);
    cout << "function1: " << gsl_vector_get(s.x, 0) << endl;

    function2(&s);
    cout << "function2: " << gsl_vector_get(s.x, 0) << endl;

    return 0;
}

1 Ответ

1 голос
/ 03 декабря 2010

Внутри function1 и function2 вы делаете копию объекта struct1, который вы создаете в функции main(). Эти копии имеют одинаковый указатель x. Когда вызывается деструктор для каждой из этих копий, вызывается gsl_vector_free, поэтому вы пытаетесь вызвать его три раза по одному и тому же указателю:

  • один раз в function1, когда s уничтожен
  • один раз в function2, когда s уничтожен
  • один раз в main, когда s уничтожен

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

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

...