سؤال

لدي نوع مصفوفة يحتوي على أ void* صفيف، يمثل مصفوفة من الكائنات (التي تكون جميعها من نوع واحد في مصفوفة معينة، على سبيل المثال، جميع الأعداد الصحيحة في لغة C، أو جميع الأعداد العشرية، أو الزوجية، أو مجموعة متنوعة من البنيات، أو ربما حتى كل روبي VALUEس).

يبدو أن تخصيص الذاكرة وجمع البيانات المهملة يعملان بشكل صحيح حتى أحاول إنشاء مصفوفة VALUEس.

لقد حددت وظيفة العلامة التالية:

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 لوظيفة العلامة.

لكنني أتلقى خطأً عندما أختبر بعضًا من 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 هي جزء من روبي الذي أفهمه على الأقل - كما أن segfault الخاص بي مطابق تقريبًا لـ هذا الأثر, ، والذي ينسبه الملصق إلى GC.

لذا أسئلتي:

  1. إذا كان GC، ما هي الطريقة المناسبة لوضع علامة على مجموعة من VALUEس؟

  2. إذا لم يكن GC، فكيف يمكنني تشخيص هذا النوع من الأخطاء؟لم يسبق لي أن رأيت أي شيء مثل ذلك.

يحرر:

وتبين أن هذا مثال على الفشل في التهيئة VALUEتم إنشاؤها في C.

وبعبارة أخرى، تأكد من القيام بذلك *(VALUE*)a = INT2FIX(0) قبل أن تحاول الوصول a.

ما زلت أعتقد أن السؤال ذو صلة.لم أتمكن من العثور على أي أمثلة جيدة حقًا لوضع العلامات على مجموعة القمامة النظيفة والمسحية، على StackOverflow أو في أي مكان آخر.إذا كان بإمكانك تقديم مثل هذا المثال و/أو الشرح، فسوف أضع علامة عليه كإجابة صحيحة على هذا السؤال.

هل كانت مفيدة؟

المحلول

يعمل GC الخاص بعلامة روبي واكتساحها على مرحلتين.

المرحلة الأولى تمثل الكائنات الحية.إنه يعمل بشكل متكرر عن طريق استدعاء وظيفة وضع العلامات لكل "كائنات حية" معروفة.يتم إنتاج المجموعة الأولية من الكائنات الحية عن طريق مسح حزمة C لكل خيط روبي معروف أو لكل كائن عالمي مسجل (توجد وظيفة C لتسجيل/إلغاء تسجيل الكائنات "الحية المعروفة").يجب أن تستدعي وظيفة وضع العلامات للكائن X rb_gc_mark لكل كائن يشير إليه X.بمعنى آخر، ما تفعله هو بالضبط ما يجب عليك فعله.

ومع ذلك، كما لاحظت لاحقًا، لا توجد أي قيمة VALUE محتملة تمثل كائن روبي صالحًا.ومع ذلك، أعتقد أن التهيئة باستخدام Qnil (أي.nil) سيكون أكثر روبي العش.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top