2010-12-03 70 views
1

您能解釋我的代碼在這裏發生了什麼嗎?我不確定是否正確使用析構函數或不在結構中。在結構中釋放gsl向量

隨着析構函數在那裏我得到:
功能1:23
功能2:8.86183e-317
* glibc的檢測 ./a:雙重釋放或腐敗(fasttop):0x000000000111b010 * *

如果我只是註釋掉析構函數,我得到:
功能1:23
功能2: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; 
} 
+0

你爲什麼使用`void *`? – 2010-12-03 18:15:51

回答

1

內的function1function2你讓您在main()函數創建struct1對象的副本。這些副本具有相同的指針x。當這些副本的析構函數被調用時,gsl_vector_free被調用,所以你嘗試調用三次對同一指針:

    function1
  • 一次當sfunction2被破壞
  • 一次當s是在main破壞
  • 一旦當s被破壞

你需要實現一個拷貝構造函數和拷貝賦值運算符該類。任何時候你擁有一個擁有資源的類,你都需要實現這兩個函數和一個析構函數。資源就是任何需要在完成使用時清理的資源。

在您的示例代碼中,封裝類中的所有分配和釋放將會好得多,以便您可以使用該類而不用擔心它。讓班級實際管理其資源。

+0

好的,但是如果我不知道當初始化struct(class)時向量x應該有多大,該怎麼辦?將它分配給大小1,然後在我知道它應該是多少時重新分配它是不是一個好主意? – evencoil 2010-12-03 18:20:25