我正在使用C擴展方法來創建一個新的紅寶石數組,但RARRAY_LEN沒有被設置。難道我做錯了什麼?爲什麼RARRAY_LEN沒有被分配?
long int max = 4;
VALUE rAry;
rAry = rb_ary_new2(max);
printf("allocated: %lu\n", RARRAY_LEN(rAry));
輸出:
allocated: 0
我正在使用C擴展方法來創建一個新的紅寶石數組,但RARRAY_LEN沒有被設置。難道我做錯了什麼?爲什麼RARRAY_LEN沒有被分配?
long int max = 4;
VALUE rAry;
rAry = rb_ary_new2(max);
printf("allocated: %lu\n", RARRAY_LEN(rAry));
輸出:
allocated: 0
顯然rb_ary_store(OBJ,索引,val)的需要被用於遞增RARRAY_LEN。奇怪的是,一個如此重要的方法基本上沒有記錄。
從array.c
(紅寶石1.8.6): #define RARRAY_LEN(s) (RARRAY(s)->len)
RARRAY(s)->len
相同Array#length
。
rb_ary_new2(4)
與Array.new(4)
不一樣。
VALUE
rb_ary_new2(len)
long len;
{
return ary_new(rb_cArray, len);
}
VALUE
rb_ary_new()
{
return rb_ary_new2(ARY_DEFAULT_SIZE);
}
ARY_DEFAULT_SIZE
定義爲16
。
什麼是隻爲數組分配內存 - 但不填充它。當您知道數組的最終大小時使用它,因此不必動態調整大小。
你想用於你的意圖的是rb_ary_new3
或rb_ary_new4
。
從Programming Ruby: The Pragmatic Programmer's Guide:
VALUE rb_ary_new3(long length, ...")
返回給定長度的新Array
並填充了剩餘的參數。
VALUE rb_ary_new4(long length, VALUE *values")
返回給定長度和填充與C數組值的新Array
。
請注意,這些函數要求您爲每個元素提供一個值。因此,您需要執行以下操作:rAry = rb_ary_new3(4, Qnil, Qnil, Qnil, Qnil)
以複製Array.new(4)
。如果你提供的參數較少,你會在Ruby中出現奇怪的行爲。 (沒有例外 - 儘管事實上你得到了一個無效的對象。)
這是因爲你在C中創建的數組是空的 - 它只是爲4個項目分配了內存。它是因爲你填充它而增加的。在我發佈的答案更多細節。 – thomthom