Resize arrays in mutable structs

In my Deldir package I use ccall on a code with 17 arguments that are all vectors. I have collected those in a mutable struct. When executing the ccall the content of the vectors in the struct are replaced.

If the Fortran code returns errors I have to increase the size of some of the arrays and use ccall again. This is the reason I use a mutable struct. But do I risk running into problems with a resize! used directly on a field, i.e., like this:

mutable struct Foo
    a::Vector{Float64}
end

foo = Foo(rand(2))
resize!(foo.a, 3)

I am not sure if I understand your question. However, it seems to me that you do not need to use a mutable struct only because you may call resize! over some Vectors that are in the struct fields. If the struct was immutable you could call resize! over the Vector fields anyway.

3 Likes

I didn’t realize that was possible with a struct - thanks :slight_smile:
I’m not sure if something breaks subtly by resizing vectors in a (mutable) struct.

I have to admit that I have never used ccall, however, there should exist no difference between vectors created originally with some size, and resized vectors. So it is hard to me to see a case where this matters. Are the vectors created in the Julia side? Fortran save some state between the calls (like the pointer)? Seem to me like a safe thing to do. But I think the house specialist is @yuyichao.

The vectors are created in Julia and modified by Fortran. That part seems to work. Depending on the output I may have to increase the size of the array – also in Julia – and call the Fortran code again.

It has not caused any problem yet. I was just wondering if this way of modifying an instance of a struct could cause issues.

There is absolutely no problem with resizing a Vector contained in a struct or mutable struct in Julia. It’s a perfectly normal and common thing to do. The only potential issue is if some other part of your program assumed that the exact memory address of that vector’s data would be constant forever, since resizing a Vector can cause its underlying data to be moved around. This isn’t a problem for purely Julia code, but it could be an issue when interacting with C/FORTRAN.

For example, if you passed that Vector as a Ptr{Float64} to your FORTRAN code, and that code stored that address for later use, then you could end up in a situation where your FORTRAN code was still pointing to the old data address after the resize.

From what I can tell, it doesn’t sound like you’re doing that, so I don’t see any problem.

5 Likes

Okay. Thanks a lot for clarifying :slight_smile: