У меня есть матричный тип, который содержит массив void*
, представляющий массив объектов (которые относятся к одному типу в данной матрице, например, все целые числа C, все числа с плавающей запятой, двойные числа, различные структуры иливозможно даже все Ruby VALUE
s).
Распределение памяти и сборка мусора, кажется, работают правильно, пока я не попытаюсь создать матрицу из VALUE
s.
У меня есть следующая функция пометкиопределено:
void mark_dense_storage(void* s) {
size_t i;
DENSE_STORAGE* storage = (DENSE_STORAGE*)s;
if (storage && storage->dtype == RUBY_OBJECT)
for (i = 0; i < count_dense_storage_elements(s); ++i)
rb_gc_mark(*((VALUE*)(storage->elements + i*sizeof(VALUE)));
}
Таким образом, маркировка выполняется только в том случае, если это матрица VALUE
, в противном случае NULL
передается в Data_Wrap_Struct
для функции маркировки.
Но я 'я получаю segfault, когда я тестирую некоторые VALUE
матричные функции (см. суть) .
В частности, кажется, что segfault при первом вызове метода Ruby всамый первый объект в массиве VALUE*
:
C[i+j*ldc] = rb_funcall(C[i+j*ldc], nm_id_mult, 1, beta); // C[i+j*ldc] = C[i+j*ldc]*beta
nm_id_mult
- это глобальный объект, определенный в моей функции Init
как rb_intern("*")
.
Возможно, это непроблема сбора мусора, но GC - это часть Ruby, которую я понимаюпо крайней мере - и мой segfault также почти идентичен этому следу , который плакат приписывает GC.
Итак, мои вопросы:
Если это GC, как правильно пометить массив VALUE
с?
Если это не GC, как мне диагностировать этот тип ошибки?Я никогда не видел ничего подобного.
РЕДАКТИРОВАТЬ:
Оказывается, что это пример неудачной инициализации VALUE
sсоздан в C.
Другими словами, обязательно сделайте *(VALUE*)a = INT2FIX(0)
, прежде чем пытаться получить доступ к a
.
Я все еще думаю, что вопрос актуален.Мне не удалось найти действительно хороших примеров маркировки для уборки мусора, в StackOverflow или где-либо еще.Если вы можете предоставить такой пример и / или объяснение, я отмечу это как правильный ответ на этот вопрос.