-
Notifications
You must be signed in to change notification settings - Fork 69
Open
Description
Case
- a c++ api returns an instance of std::vector
- a ruby function returns a reference to an element of the std::vector
- use the ruby function, the return value contains invalid data (and may cause a crash when the C++ side uses pointers)
Reproduce
c++ code
struct Point{
int x() const { return m_x; }
int y() const { return m_y; }
int m_x, m_y;
};
extern "C" void Init_qtcore()
{
return detail::cpp_protect([] {
Class rb_cPoint = define_class<Point>("Point")
.define_method("x", &Point::x)
.define_method("y", &Point::y);
define_global_function("get_point_list", []() -> std::vector<Point> {
std::vector<Point> vec;
vec.push_back(Point { 1, 2 });
return vec;
});
});
}ruby code
irb(main):001> GC.disable
=> false
irb(main):002* def find_element
irb(main):003* get_point_list[0]
irb(main):004> end
=> :find_element
irb(main):005> e = find_element
=> #<Point:0x00007f351c366ed0>
irb(main):006> "(#{e.x}, #{e.y})"
=> "(1, 2)"
irb(main):007> GC.enable; GC.start # the point_list destroyed ?
=> nil
irb(main):008> "(#{e.x}, #{e.y})" # invalid data
=> "(348141680, 21847)"Fix
- the point list should lives longer than the elements.
- or return a copy of element ?
- or add a note to the document
std support, recommanding users usePoint#dupwhen necessary ?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels