paulsmith / gogeos

Go library for spatial data operations and geometric algorithms (Go bindings for GEOS)
http://paulsmith.github.io/gogeos/
MIT License
280 stars 79 forks source link

Fixed a bug in encodeWkb() for Windows #15

Open andreacomparini opened 8 years ago

andreacomparini commented 8 years ago

Found a bug in encodeWkb() for windows. A buffer allocated in geos_c.dll whith malloc() cannot simply be freed with C.free(). Must use cGEOSFree(). Now all tests pass. The modified code follows:

func encodeWkb(e *wkbEncoder, g *Geometry, fn func(*C.GEOSWKBWriter, *C.GEOSGeometry, *C.size_t) *C.uchar) ([]byte, error) {
    var size C.size_t
    bytes := fn(e.w, g.g, &size)
    if bytes == nil {
        return nil, Error()
    }
    ptr := unsafe.Pointer(bytes)
    defer cGEOSFree((*C.void)(ptr))     //instead of C.free(ptr)

    l := int(size)
    var out []byte

    for i := 0; i < l; i++ {
        el := unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(C.uchar(0))*uintptr(i))
        out = append(out, byte(*(*C.uchar)(el)))
    }

    return out, nil 
} 
l4d2boomer commented 2 years ago

Hi. Thanks for the solution. It really helped me. Btw, can u explain the reason for that?

andreacomparini commented 2 years ago

Hi. Thanks for the solution. It really helped me. Btw, can u explain the reason for that?

Hi. When you allocate memory in dll (win) with malloc you use a specific heap of dll, not a system wide one. So you must free the same memory using the same pointer local to dll code. The way to do this is to call a public entry point that calls free on the ptr of the specific heap from which it was allocated. GEOSFree is such a public method.