«IndexOutOfBoundsException: доступ за пределами сегмента...» при доступе к указателю, считанному из MemorySegment
Я пытаюсь протестировать функции внешних функций и памяти Java 21. Вот мой код:
public static void main(String[] args) {
// 1. Find foreign function on the C library path
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle radixsort = linker.downcallHandle(stdlib.find("radixsort").orElseThrow(), FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_CHAR));
// 2. Allocate on-heap memory to store four strings
String[] javaStrings = {"mouse", "cat", "dog", "car"};
// 3. Use try-with-resources to manage the lifetime of off-heap memory
try (Arena offHeap = Arena.ofConfined()) {
// 4. Allocate a region of off-heap memory to store four pointers
MemorySegment pointers = offHeap.allocateArray(ValueLayout.ADDRESS, javaStrings.length);
// 5. Copy the strings from on-heap to off-heap
for (int i = 0; i < javaStrings.length; i++) {
MemorySegment cString = offHeap.allocateUtf8String(javaStrings[i]);
pointers.setAtIndex(ValueLayout.ADDRESS, i, cString);
assert cString.getUtf8String(0).length() > 0;
}
// 6. Sort the off-heap data by calling the foreign function
radixsort.invoke(pointers, javaStrings.length, MemorySegment.NULL, '\0');
// 7. Copy the (reordered) strings from off-heap to on-heap
for (int i = 0; i < javaStrings.length; i++) {
MemorySegment cString = pointers.getAtIndex(ValueLayout.ADDRESS, i);
javaStrings[i] = cString.getUtf8String(0);
}
} // 8. All off-heap memory is deallocated here
catch (Throwable e) {
throw new RuntimeException(e);
}
assert Arrays.equals(javaStrings, new String[]{"car", "c∞at", "dog", "mouse"}); // true
}
но я сталкиваюсь с этой ошибкой:
Exception in thread "main" java.lang.RuntimeException: java.lang.IndexOutOfBoundsException: Out of bound access on segment MemorySegment{ heapBase: Optional.empty address:105553153094096 limit: 0 }; new offset = 0; new length = 1
На линии:
javaStrings\[i\] = cString.getUtf8String(0);
Кажется, чтоMemorySegment cString = pointers.getAtIndex(ValueLayout.ADDRESS, i);
возвращает MemorySegment с byteSize = 0
Когда я используюcString.getUtf8String(0);
в исходной cString я не обнаружил ошибок.
Кажется, чтоpointers.setAtIndex
иpointers.getAtIndex
не сохраняйте byteSize MemorySegment. ?