java-native-access/jna · error · java.lang.IllegalArgumentException
Structure array elements must use contiguous memory (bad bac
Error message
Structure array elements must use contiguous memory (bad backing address at Structure array index
What it means
Before operating on an array of Structures as a contiguous native block, Structure.structureArrayCheck verifies that every element's backing native address equals base + index*size. If an element was allocated separately (its own Memory/auto-allocated pointer) the array is not contiguous and marshalling the whole array would corrupt data, so it throws IllegalArgumentException naming the first offending index.
Source
Thrown at src/com/sun/jna/Structure.java:2322
super.clear();
}
@Override
public String toString() {
return "auto-" + super.toString();
}
}
private static void structureArrayCheck(Structure[] ss) {
if (Structure.ByReference[].class.isAssignableFrom(ss.getClass())) {
return;
}
Pointer base = ss[0].getPointer();
int size = ss[0].size();
for (int si=1;si < ss.length;si++) {
if (ss[si].getPointer().peer != base.peer + size*si) {
String msg = "Structure array elements must use"
+ " contiguous memory (bad backing address at Structure array index " + si + ")";
throw new IllegalArgumentException(msg);
}
}
}
public static void autoRead(Structure[] ss) {
structureArrayCheck(ss);
if (ss[0].array == ss) {
ss[0].autoRead();
}
else {
for (int si=0;si < ss.length;si++) {
if (ss[si] != null) {
ss[si].autoRead();
}
}
}
}
View on GitHub (pinned to d036ad9781)
Solutions
- Allocate the array contiguously with s = (S)new S().toArray(size) and use those elements, instead of constructing each element with its own memory
- If elements must live at separate addresses, pass them individually (or as an array of pointers ByReference) rather than as one Structure[] native block
- Never call useMemory() on elements after forming a Structure[]; keep one shared backing Memory for the whole array
- Verify element pointers before marshalling: check ss[i].getPointer().peer offsets yourself when attaching to foreign memory
Example fix
// before MyStruct[] arr = new MyStruct[n]; for (int i=0;i<n;i++) arr[i] = new MyStruct(new Memory(size)); // non-contiguous // after MyStruct[] arr = (MyStruct[]) new MyStruct().toArray(n); // contiguous backing
Defensive patterns
Strategy: validation
Validate before calling
<S extends Structure> boolean isContiguous(S[] ss) {
if (ss == null || ss.length == 0) return true;
Pointer base = ss[0].getPointer();
long size = ss[0].size();
for (int i = 1; i < ss.length; i++) {
if (ss[i].getPointer().peer != base.peer + size * i) return false;
}
return true;
} Try / catch
try {
Structure.autoRead(array);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("contiguous memory")) {
throw new IllegalStateException("Reallocate array with new MyStruct().toArray(n)");
}
throw e;
} Prevention
- Always allocate Structure arrays via new MyStruct().toArray(n) instead of filling an array of separately allocated instances
- Do not call useMemory() on individual elements of a shared array
- When wrapping foreign memory, attach the whole block once and derive elements from it
- Assert pointer offsets in tests when adopting native-returned structures into an array
When it happens
Trigger: Creating Structure elements with individual new Memory(...) pointers, mixing auto-allocated elements with a shared backing buffer, using Structure.toArray on elements that were separately attached to foreign memory, or modifying one element's pointer after array creation.
Common situations: Manually calling useMemory() on individual elements of what is intended to be one array, reusing Structure objects allocated earlier at different addresses inside an array, or building an array from structures returned by native code at scattered addresses and then passing it as a native array.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Function <name> declared Structure[] at parameter <index> bu
- Function <name> declared Structure[] at parameter <index> bu
- Structure array must have non-zero length
- Need an initialized array
- Structure exceeds provided memory bounds
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/f09835d7bba8aa92.
Report an issue: GitHub.