我在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获得的。
答案 0 :(得分:0)
使用ALLOC_N
代替malloc
进行了修正。 http://clalance.blogspot.com/2011/01/writing-ruby-extensions-in-c-part-12.html很有帮助,虽然它说malloc应该可以工作。