{"record":{"id":"f09835d7bba8aa92","repo":"java-native-access/jna","slug":"structure-array-elements-must-use-contiguous-memory-bad","errorCode":null,"errorMessage":"Structure array elements must use contiguous memory (bad backing address at Structure array index ","messagePattern":"Structure array elements must use contiguous memory \\(bad backing address at Structure array index ","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Structure.java","lineNumber":2322,"sourceCode":"            super.clear();\n        }\n        @Override\n        public String toString() {\n            return \"auto-\" + super.toString();\n        }\n    }\n\n    private static void structureArrayCheck(Structure[] ss) {\n        if (Structure.ByReference[].class.isAssignableFrom(ss.getClass())) {\n            return;\n        }\n        Pointer base = ss[0].getPointer();\n        int size = ss[0].size();\n        for (int si=1;si < ss.length;si++) {\n            if (ss[si].getPointer().peer != base.peer + size*si) {\n                String msg = \"Structure array elements must use\"\n                    + \" contiguous memory (bad backing address at Structure array index \" + si + \")\";\n                throw new IllegalArgumentException(msg);\n            }\n        }\n    }\n\n    public static void autoRead(Structure[] ss) {\n        structureArrayCheck(ss);\n        if (ss[0].array == ss) {\n            ss[0].autoRead();\n        }\n        else {\n            for (int si=0;si < ss.length;si++) {\n                if (ss[si] != null) {\n                    ss[si].autoRead();\n                }\n            }\n        }\n    }\n","sourceCodeStart":2304,"sourceCodeEnd":2340,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Structure.java#L2304-L2340","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nMyStruct[] arr = new MyStruct[n];\nfor (int i=0;i<n;i++) arr[i] = new MyStruct(new Memory(size)); // non-contiguous\n// after\nMyStruct[] arr = (MyStruct[]) new MyStruct().toArray(n); // contiguous backing","handlingStrategy":"validation","validationCode":"<S extends Structure> boolean isContiguous(S[] ss) {\n    if (ss == null || ss.length == 0) return true;\n    Pointer base = ss[0].getPointer();\n    long size = ss[0].size();\n    for (int i = 1; i < ss.length; i++) {\n        if (ss[i].getPointer().peer != base.peer + size * i) return false;\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n    Structure.autoRead(array);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"contiguous memory\")) {\n        throw new IllegalStateException(\"Reallocate array with new MyStruct().toArray(n)\");\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["jna","structure","memory-layout","contiguous-array"],"backgroundTag":"invalid-argument-value","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}