Silverfrost Forums

Welcome to our forums

Constructed character variable overflow

3 Oct 2007 9:11 #2289

I have a program, ostensibly working fine (but with occasional non-reproducible weird little problems that point towards some sort of subtle memory corruption), in which I discovered the following error yesterday.

A derived data type to represent a linked list:

  type stack_id
    character (len = worlen) has_control
    type (stack_id), pointer :: had_control        
  end type stack_id

and the following constructor statement elsewhere in the program:

  stack_item = stack_id (routine_name, stack_head)

where the value of routine_name is, on occasion, one character longer than is allowed for in the derived data type 😮ops: 😮ops: .

Can someone tell me the immediate consequence of this error? I am presuming that memory corruption occurs ... if so, is it necessarily of the pointer that follows the character variable in the derived data type?

Is it something that Checkmate should pick up? I can't remember if it is even able to pick up overflow in basic character variables.

Andy

3 Oct 2007 11:51 #2291

Andy

I would expect the character variable to be truncated and this appears to be the case below. This program gives a warning message in one case. CHECKMATE includes a check for the use of undefined character variables.

integer,parameter::worlen = 6
type stack_id 
 character (len = worlen) has_control 
 type (stack_id), pointer :: had_control 
end type stack_id 

character(7) routine_name
type(stack_id),target:: stack_item
type(stack_id):: stack_item2
type(stack_id), pointer :: stack_head

NULLIFY(stack_head)
routine_name = '1234567'
stack_item = stack_id(routine_name, stack_head)
print*, stack_item%has_control 
stack_item2 = stack_id('abcdefgh', stack_item)
print*, stack_item2%has_control, ' --- ', stack_item2%had_control%has_control
end
3 Oct 2007 1:36 #2292

Paul,

Many thanks for your help. I have made several modlets to your applet, to rule out a number of possible further gotchas:

program chover integer, parameter :: worlen = 8 type stack_id character (len = worlen) has_control type (stack_id), pointer :: had_control end type stack_id character (9) routine_name type(stack_id), pointer :: stack_item, stack_head NULLIFY (stack_head) routine_name = '123456789' call push_name (routine_name) print*, stack_item%has_control call push_name ('abcdefghi') print*, stack_item%has_control, ' --- ', stack_item%had_control%has_control contains subroutine push_name (routine_name) character (len = *) routine_name allocate (stack_item) stack_item% has_control = routine_name stack_item% had_control ⇒ stack_head stack_head ⇒ stack_item return end subroutine push_name end program chover

  1. I delegated the constructor statement to a subroutine (as in my actual program) so that the compiler was not able to issue a comment about truncation at compile time.

  2. I changed worlen to 8 to rule out the possibility that the slack space resulting from 4-byte alignment was coming to the rescue.

  3. I changed the constructor statement to two separate statements, an assignment and a pointer assignment, because I wanted to single-step and check that overflow was not occurring and then being corrected, by virtue of the construction taking place 'left to right'.

However, it seems that I was worrying about nothing: in every case, truncation rather than overflow occurs. Score 1 for FORTRAN rather than C?!

Andy

Please login to reply.