- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a project that I have recently moved from Visual Fortran 6.5 to Intel Fortran 8.1. The code has the following data structure.
pointer (ptr_desired_stations, desired_stations)
structure /STATION_LIST/
integer id
integer ichan
character city*20
character state*2
character sta_type*1
character fill*1
logical*2 class_a
character offset*1
end structure
record /STATION_LIST/ desired_stations(*)
I allocated memory for the object as follows.if (ptr_desired_stations .ne. 0)& call report_mem_error_1(routine, pointer_name)
c
c Allocate memory
cptr_desired_stations = malloc(n_des_sta * 35)if (ptr_desired_stations .eq. 0)& call report_mem_error(routine, pointer_name, n_des_sta)return
The problem happens when I try to free the memory.
if
(ptr_desired_stations .eq. 0)& call report_mem_error_2(routine, pointer_name)call free(ptr_desired_stations)ptr_desired_stations = 0returnI get a "Microsoft Visual C++ Debug library" error that says "DAMAGE: after Normal block(#104659) at 0x06F2B648.
This error does not come up when I compile the program using Visual Fortran 6.5, only with the Intel Fortran 8.1?
Can someone please tell me why it is coming up(though I believe the size isn't right for the memory allocation, but I've
tried changing the variabl e sizes and that didn't work) and why it only comes up in the new compiler(is it a problem that the
old compiler misses it)?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just noticed that the "logical*2 class_a" should be "logical class_a", which is how it is in the original code. The same error occurred when I
tried "logical*2 class_a".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Version 10.1 is current.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have tried to adjust the code so use SIZEOF(). The problem is, SIZEOF() keeps returning the value 4, and I know that is not right. Here is the code again(original post formatting wasn't good).
pointer (ptr_desired_stations, desired_stations)I changed the earlier code to
structure /STATION_LIST/
integer id
integer ichan
character city*20
character state*2
character sta_type*1
character fill*1
logical class_a
character offset*1
end structure
record /STATION_LIST/ desired_stations(*)
tmp_size = sizeof(STATION_LIST)
ptr_desired_stations = malloc(n_des_sta * tmp_size)
As I said earlier, when I do this I get "tmp_size = 4". This causes an unrelated error(at least, an error not immediately connected to "ptr_desired_stations"). The line that causes the error is
write(time_string, 1000) int(hours),
& int(60*mod(hours, 1.0)),
& int(60*mod(60*mod(hours, 1.0), 1.0))
The error message is
Insufficient memory to allocate Fortran RTL message buffer, message #41.
This seems to be a memory corruption error. Does SIZEOF() need an instance of STATION_LIST?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The compiler does no memory range checking other than array and string bounds.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem is indeed in your hard-coded size of the structure (35 or 37, whichever). In reality, it would be 40 -- and that would be returned by SIZEOF(tempStationList). The value of 40 comes as consequence of the "natural alignment" feature of computer architecture -- by default, the processor "likes" that n-byte variables are aligned on an address divisible by n. As consequence, the "real" size of structure is a multiply of size of its greatest (non-character) member; that means that you will have 3 "unused" bytes after each member of desired_stations array. Now, you malloc() less memory that you actually use, overwriting its tail in the process.
SEQUENCE keyword (or !DEC$PACK metacommand, I'm not sure if the former applies to STRUCTUREs) should prevent the "natural alignment" to occur, i.e. will "densely pack" the structure members. It will also reduce performance though. As Steve said, best, use SIZEOF with a dummy variable of appropriate type to find out the size.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page