summaryrefslogtreecommitdiff
path: root/ext/fiddle
diff options
context:
space:
mode:
authorChris Seaton <chris@chrisseaton.com>2020-05-19 00:12:47 +0100
committerNobuyoshi Nakada <nobu@ruby-lang.org>2020-05-23 14:34:07 +0900
commit3015a7aae7ddc9b63149df34b1f12366e07a9563 (patch)
treed8717bceae57a47f2257f8701c02423d51dab62f /ext/fiddle
parent24b615e82ee327a9ac583937de746ba12dde2d6a (diff)
[ruby/fiddle] Improve documentation on how to correctly free memory and free memory in tests (#33)
https://github.com/ruby/fiddle/commit/e59cfd708a
Diffstat (limited to 'ext/fiddle')
-rw-r--r--ext/fiddle/lib/fiddle/struct.rb11
-rw-r--r--ext/fiddle/pointer.c26
2 files changed, 31 insertions, 6 deletions
diff --git a/ext/fiddle/lib/fiddle/struct.rb b/ext/fiddle/lib/fiddle/struct.rb
index 8a48a1cb8b..259903d25c 100644
--- a/ext/fiddle/lib/fiddle/struct.rb
+++ b/ext/fiddle/lib/fiddle/struct.rb
@@ -73,7 +73,12 @@ module Fiddle
#
# MyStruct = Fiddle::CStructBuilder.create(Fiddle::CUnion, types, members)
#
- # obj = MyStruct.allocate
+ # obj = MyStruct.malloc
+ # begin
+ # ...
+ # ensure
+ # Fiddle.free obj.to_ptr
+ # end
#
def create(klass, types, members)
new_class = Class.new(klass){
@@ -112,7 +117,7 @@ module Fiddle
# Allocates a C struct with the +types+ provided.
#
- # When the instance is garbage collected, the C function +func+ is called.
+ # See Fiddle::Pointer.malloc for memory management issues.
def CStructEntity.malloc(types, func = nil)
addr = Fiddle.malloc(CStructEntity.size(types))
CStructEntity.new(addr, types, func)
@@ -267,7 +272,7 @@ module Fiddle
# Allocates a C union the +types+ provided.
#
- # When the instance is garbage collected, the C function +func+ is called.
+ # See Fiddle::Pointer.malloc for memory management issues.
def CUnionEntity.malloc(types, func=nil)
addr = Fiddle.malloc(CUnionEntity.size(types))
CUnionEntity.new(addr, types, func)
diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c
index 117cc9b826..7c60da477a 100644
--- a/ext/fiddle/pointer.c
+++ b/ext/fiddle/pointer.c
@@ -193,14 +193,34 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
/*
* call-seq:
- *
* Fiddle::Pointer.malloc(size, freefunc = nil) => fiddle pointer instance
*
+ * == Examples
+ *
+ * # Relying on the garbage collector - may lead to unlimited memory allocated before freeing any, but safe
+ * pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
+ * ...
+ *
+ * # Manual freeing
+ * pointer = Fiddle::Pointer.malloc(size)
+ * begin
+ * ...
+ * ensure
+ * Fiddle.free pointer
+ * end
+ *
+ * # No free function and no call to free - the native memory will leak if the pointer is garbage collected
+ * pointer = Fiddle::Pointer.malloc(size)
+ * ...
+ *
* Allocate +size+ bytes of memory and associate it with an optional
* +freefunc+ that will be called when the pointer is garbage collected.
- *
* +freefunc+ must be an address pointing to a function or an instance of
- * Fiddle::Function
+ * +Fiddle::Function+. Using +freefunc+ may lead to unlimited memory being
+ * allocated before any is freed as the native memory the pointer references
+ * does not contribute to triggering the Ruby garbage collector. Consider
+ * manually freeing the memory as illustrated above. You cannot combine
+ * the techniques as this may lead to a double-free.
*/
static VALUE
rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)