Skip to content

Commit 6df97d2

Browse files
authored
Merge pull request #131 from kevinmatthe/bugfix/fix_double_free
🐛 fix(jieba): 修复内存释放问题
2 parents 51c61c7 + bcb7e0c commit 6df97d2

2 files changed

Lines changed: 17 additions & 4 deletions

File tree

jieba.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ package gojieba
77
*/
88
import "C"
99
import (
10+
"fmt"
11+
"os"
1012
"runtime"
13+
"sync/atomic"
1114
"unsafe"
12-
"os"
13-
"fmt"
1415
)
1516

1617
type TokenizeMode int
@@ -28,11 +29,12 @@ type Word struct {
2829

2930
type Jieba struct {
3031
jieba C.Jieba
32+
freed int32
3133
}
3234

3335
func NewJieba(paths ...string) *Jieba {
3436
dictpaths := getDictPaths(paths...)
35-
37+
3638
// check if the dictionary files exist
3739
for _, path := range dictpaths {
3840
if _, err := os.Stat(path); os.IsNotExist(err) {
@@ -54,14 +56,17 @@ func NewJieba(paths ...string) *Jieba {
5456
ipath,
5557
spath,
5658
),
59+
0,
5760
}
5861
// set finalizer to free the memory when the object is garbage collected
5962
runtime.SetFinalizer(jieba, (*Jieba).Free)
6063
return jieba
6164
}
6265

6366
func (x *Jieba) Free() {
64-
C.FreeJieba(x.jieba)
67+
if atomic.CompareAndSwapInt32(&x.freed, 0, 1) { // only free once
68+
C.FreeJieba(x.jieba)
69+
}
6570
}
6671

6772
func (x *Jieba) Cut(s string, hmm bool) []string {

jieba_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package gojieba
33
import (
44
"fmt"
55
"reflect"
6+
"runtime"
67
"strings"
78
"testing"
89
)
@@ -267,3 +268,10 @@ func BenchmarkExtractor(b *testing.B) {
267268
x.ExtractWithWeight(s, 10)
268269
}
269270
}
271+
272+
func TestTypicalDoubleFree(t *testing.T) {
273+
x := NewJieba()
274+
defer x.Free()
275+
276+
runtime.GC() // call GC to run finalizers
277+
}

0 commit comments

Comments
 (0)