Ruby C宝石内存污染运行之间

时间:2015-06-19 20:20:47

标签: c ruby gem

我在C中写了一个宝石,它似乎在运行之间保持污染的内存。

我在过去注意到了这一点,但终于发现了如何通过在Spring中使用RSpec调用Gem来一致地重现它。在重新启动Spring后运行此单个RSpec示例时,示例始终通过。但是后续运行而不重新启动Spring会导致垃圾数据。进一步的后续运行会产生相同的垃圾数据。

示例:

$ spring stop
Spring stopped.
$ spring rspec ..._spec.rb:122
...
1 example, 0 failures

$ spring rspec ..._spec.rb:122
...
Failures:
...
       expected collection contained:  [7]
       actual collection contained:    [1333155159]
$ spring rspec ..._spec.rb:122
...
Failures:
...
       expected collection contained:  [7]
       actual collection contained:    [1333155159]

$ spring stop
Spring stopped.
$ spring rspec ..._spec.rb:122
...
1 example, 0 failures

$ spring rspec ..._spec.rb:122
...
Failures:
...
       expected collection contained:  [7]
       actual collection contained:    [117372691]
$ spring rspec ..._spec.rb:122
...
Failures:
...
       expected collection contained:  [7]
       actual collection contained:    [117372691]

C不应该在运行之间持久存在。唯一的全局声明是常量,结构定义,函数和模块名称本身。例如(简化为每种类型的声明中的一种,除了标题):

#include <ruby.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define SOME_CONSTANTS 100

struct some_structs {
  long id;
  double amount;
};

static long some_functions();

VALUE MyModuleName = Qnil;
VALUE internal_function_name(VALUE self, VALUE rb_data, VALUE rb_options);

void Init_my_gem() {
  MyModuleName = rb_define_module("MyModuleName");
  rb_define_singleton_method(MyModuleName, "exposed_function_name",
    internal_function_name, 2);
}

感谢您就可能发生的事情提出任何想法。

修改

我把它分开了:

printf("A orders[0].products[0]->id: %lu\n", orders[0].products[0]->id);
VALUE rb_best_orders = rb_ary_new();
printf("B orders[0].products[0]->id: %lu\n", orders[0].products[0]->id);

Output:
A orders[0].products[0]->id: 7
B orders[0].products[0]->id: 140735021913496

请注意,订单定义为struct order *orders;,其内存是通过malloc获得的。

1 个答案:

答案 0 :(得分:0)

使用ALLOC_N代替malloc进行了修正。 http://clalance.blogspot.com/2011/01/writing-ruby-extensions-in-c-part-12.html很有帮助,虽然它说malloc应该可以工作。