Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Nullify vs. ZeroMemory

netphilou31
New Contributor II
1,057 Views

Hi,

I am frequently using derived type variables which are allocated using the malloc function, i.e., I have a derived type declaration, then a variable of that derived type and finally a pointer association to that variable. For example:

 

type TWorkspace
    sequence
    integer(4), pointer :: NUM
    integer(4), pointer :: LIST(:)
    real(8),    pointer :: X(:,:)
end type TWorkspace

type TElement
    sequence
    integer(4),       pointer :: N
    real(8),          pointer :: A(:)
    type(TWorkspace), pointer :: w
end type TElement

type(TElement) :: Element
pointer(ptrElement, Element)

ptrElement = malloc(sizeof(Element))
if (ptrElement/= NULL) call ZeroMemory(ptrElement,sizeof(Element))

allocate(Element%N)
Element%N = 0

allocate(Element%A(10))
Element%A(:) = 0.D0

allocate(Element%w)

 

Now are these two declarations identical ?

 

call ZeroMemory(loc(Element%w), sizeof(Element%w))
nullify(Element%w%NUM)
nullify(Element%w%LIST)
nullify(Element%w%X)

 

If not, I guess that I would need to change also the call to the ZeroMemory function for the parent variable "Element'".

Best regards, 

Phil.

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
1,032 Views

I'd be nervous about using ZeroMemory on a type that has array pointer components, as these have descriptors for the arrays, not just addresses, and there might be some data that isn't recreated when you allocate the pointers. It's probably OK, but if it were me, I would use the nullify statements.

View solution in original post

0 Kudos
4 Replies
jimdempseyatthecove
Honored Contributor III
1,035 Views

Both do work

 

Element%w is a pointer to a user defined type, which can be

a) unassociated

b) associated via => with a previously defined type of its type

c) associated via allocation as a new instance of its type

 

Note, a given compiler implementation may make a distinction between unassociated and undefined where the bit values are up to the whim of the compiler team. 

 

Your call to ZeroMemory(...) as well as nullify(Element%w%...) requires:

a) Element%w is associated (=> or allocated)

b) Element%w: NUM, LIST and X .NOT. be allocated (may be associate via =>, unassociated or undefined)

 

Note, in the case where NUM, LIST or X is allocated, then either method might lead to memory leak (depending on if alternate pointer exists).

Also note that LIST and X are arrays and are thus array descriptors as opposed to a mere pointer.

BTW I have been wiping large UDT's for decades with no issue.

 

Jim Dempsey

 

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,033 Views

I'd be nervous about using ZeroMemory on a type that has array pointer components, as these have descriptors for the arrays, not just addresses, and there might be some data that isn't recreated when you allocate the pointers. It's probably OK, but if it were me, I would use the nullify statements.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,030 Views

Steve,

While I agree in principal, in practice this can be error prone especially when you have very large UDT's that have 100's of member variables that are being added and/or removed and/or renamed.

 

Jim Dempsey

0 Kudos
netphilou31
New Contributor II
1,000 Views

Hi Jim and Steve,

Thanks for your replies.

@jimdempseyatthecove, when I call the ZeroMemory function, it's just after the allocation of the w component, so I have no problem with potential existing allocation of sub-items, they should not exist prior to the allocation (I have a routine to initialize, i.e. allocating the UDT, and another one to destroy it and nothing relating to allocation/association is performed elsewhere).

@Steve_Lionel, this is what I was thinking about, descriptors of pointer elements of array types. I wasn't sure if the ZeroMemory was correctly doing the job, even if it seems to be working.

I agree also with Jim about the fact that for UDTs containing a lot of items, using the nullify statement can be a bit complex to deal with because the potential issues happen only when adding a new item which is not correctly nullified at its creation; when removing or renaming components, the compiler should give an error because the item of the UDT is not existing anymore when you use it somewhere in your code, so these errors are easier to deal with.

Best regards,

Phil.

0 Kudos
Reply