C 使用ruby FFI在ruby中创建静态数组类
我想用ruby实现我自己的静态数组类。它将是一个具有固定容量的数组,数组中的所有元素都将是单一类型。 为了直接访问内存,我使用FFIGEM,它可以创建自己的C函数并在ruby程序中使用它们。 我创建了一个非常简单的C函数,它为整数数组分配内存,并返回指向内存空间的指针:C 使用ruby FFI在ruby中创建静态数组类,c,arrays,ruby,memory,ffi,C,Arrays,Ruby,Memory,Ffi,我想用ruby实现我自己的静态数组类。它将是一个具有固定容量的数组,数组中的所有元素都将是单一类型。 为了直接访问内存,我使用FFIGEM,它可以创建自己的C函数并在ruby程序中使用它们。 我创建了一个非常简单的C函数,它为整数数组分配内存,并返回指向内存空间的指针: int * create_static_array(int size) { int *arr = malloc(size * sizeof(int)); return arr; } 这是我的ruby静态数组类,它使用c
int * create_static_array(int size) {
int *arr = malloc(size * sizeof(int));
return arr;
}
这是我的ruby静态数组类,它使用create\u static\u数组:
require 'ffi'
class StaticArray
attr_accessor :pointer, :capacity, :next_index
extend FFI::Library
ffi_lib './create_array/create_array.so'
attach_function :create_static_array, [:int], :pointer
def initialize(capacity)
@capacity = capacity
@pointer = create_static_array(capacity)
@next_index = 0
end
# adds value to the next_index in array
def push(val)
@pointer[@next_index].write(:int, val)
@next_index += 1
end
# reads value at index
def [](index)
raise IndexOutOfBoundException if index >= @capacity
self.pointer[index].read(:int)
end
# print every value in index
def print
i = 0
while (i < @capacity)
puts @pointer[i].read(:int)
i += 1
end
end
end
现在让我们在arr中推一个int:
arr.push(20)
arr.print
将输出
20
0
0
0
这是有道理的。现在让我们将另一个int推到arr中:
arr.push(16)
和arr.print
再次:
4116
16
0
0
20已被4116所取代。。。我真的搞不懂这里发生了什么
FFI接口不知道指针的类型,因此它只是将其视为字节数组(请参见初始化指针类型)。请注意,虽然您确实传递了
:int
,但这是针对特定的写入
和读取
,而不是在进行索引的位置。因此,在字节偏移量0,1,2,3处写入和打印,而不是在0,4,8,12处写入和打印整数元素
在一个32位4字节整数的小尾端系统上,20的二进制值是14 00 00
,16的二进制值是10 00 00
分配4*4个字节,32个字节,前8个是
00 00 00 00 00 00 00 00
并在偏移量0处写入20
14 00 00 00 00 00 00 00
然后在偏移量1处写入16
14 10 00 00 00 00 00 00
141000
是0x00001014
或4116,然后在下一个偏移量处打印它是1000000
即16。您的目标是什么?性能、减少内存使用、与其他本机代码的交互?因此,我初始化了一个16字节的数组,而我的指针不知道我初始化的指针的类型。因此,当我试图通过索引访问特定值时,我实际上是在访问特定字节。然后,因为我指定了要读取的值的类型(read(:int)),指针理解我要从那里开始读取所有4个字节并计算一个整数。从你的解释中,我明白为了使我的程序工作,我应该将所有索引乘以4。然而,我仍然会遇到非常意外的行为…例如:arr=StaticArray.new(4)arr.print 0-268435456-1600786800 2047
我在这里做错了什么?malloc
不保证内存是零填充的,并且可能有以前使用内存时留下的东西。看起来可能是这样。所以我不明白马洛克是干什么的。。。如果您使用malloc(n)1)您不能保证有n个可用空间,2)如果您试图写入的偏移量超过了使用malloc所影响的偏移量,则实际上不会引发错误(C不提供任何处理访问无效索引问题的规范)。那么,与初始化随机指针相比,使用malloc的优势是什么呢?…1)如果malloc(n)
返回一个非空指针,则可以保证(大多数情况下,请参见Linux OOM killer),您有n个字节。但由于性能原因(使用C的常见原因之一),它不能保证将这些字节设置为任何特定的值(例如0)。如果要将其归零,可以使用saymemset
。出于安全原因,现在操作系统中的新鲜(尚未被特定进程使用)被归零(因此你看不到它是否有来自Chrome的密码),但在进程创建/销毁一些东西后,malloc将重用装满东西的内存。
14 10 00 00 00 00 00 00