Re: Dusty Deck and C memory manager, Part 1



rih5342 wrote:
This F77 code fragment is about 25 years old.

I don't know enough C to figure out what the function is doing just by
looking at it, and would like advice on how best to rewrite the C function
using either F90 or "Cray" pointers.

CVF V6.6 on Windows 2000 is the target system.

(I hope the line wrap from the cut and paste isn't
a show stopper.)

Thanks in advance.

Rob

c*************************************************
program main
REAL work(1)
POINTER iwork
INTEGER nreal

INTERFACE
SUBROUTINE getarr (i, x, iptr)
!DEC$ ATTRIBUTES reference, ALIAS:'_getarr' :: getarr
INTEGER i
REAL x(1)
POINTER :: iptr
END SUBROUTINE getarr
END INTERFACE

nreal = 5000
call getarr(nreal, work, iwork)

end program main

/*-----------------------------------------------------------------------------

CMEMC.C -- C memory management routines for use with FORTRAN.

FORTRAN entry points:

SUBROUTINE GETARR(LENGTH,ARRAY,INDEX)
__REAL ARRAY(*)
Return an index into ARRAY representing LENGTH words of available
memory. Calls Unix MALLOC(3C).
LENGTH - Number of words of memory requested.
ARRAY - Base address such that ARRAY(INDEX) represents the first
element of the new space.
INDEX - Returned index into ARRAY for the first element of the new
space. If space could not be allocated, zero is returned
for INDEX.

-----------------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include "forttype.h"
#include "fortcall.h"

/* GETARR - Return an index into REAL ARRAY representing LENGTH words of
available memory. */

__int *length;
void **index;
__float *array;

{
size_t len;
void *ptr, *malloc();
long int iaddr_unit;
__float test[2];

/* Byte-addressable, word-addressable, or what? */

iaddr_unit = (long int)&test[1] - (long int)&test[0];

/* Whatever the addressing unit, MALLOC should take len in bytes. */

len = (size_t)(*length * sizeof(__float));

/* Call MALLOC. */

ptr = malloc(len);
if (ptr == 0)
*index = 0;
else
*index = (void *)(((long int)ptr - (long int)array)/iaddr_unit + 1);

return;
}



Rather than introduce Cray pointers and use C routines to allocate memory for Fortran arrays, you could use straight F90, for example:

program main
REAL, allocatable :: work(:)
INTEGER :: nreal=5000

allocate(work(nreal))
work(1)=1.0
work(4999)=4999.0
work(5000)=5e3
write(*,20)work(1),work(4999),work(5000)
stop
20 format(1x,3ES15.4)
end program main

-- mecej4
.



Relevant Pages

  • [RFCv2][PATCH] flexible array implementation
    ... I call it a flexible array. ... storage for pointers to the second level. ... all locking must be provided by the caller. ... make sure to pass in &ptr instead of ptr. ...
    (Linux-Kernel)
  • Re: [RFCv2][PATCH] flexible array implementation
    ... I call it a flexible array. ... storage for pointers to the second level. ... all locking must be provided by the caller. ... make sure to pass in &ptr instead of ptr. ...
    (Linux-Kernel)
  • Re: Simple C containers, std::vector analog
    ... You're right about not needing to care very much about the memory ... blocks, in not knowing the ultimate size of the growable array, because ... there is no realloc function, and besides realloc might be having ... whether it's used for the list of array block pointers only or a C++ ...
    (comp.lang.c)
  • Re: Differance between Array and Pointers
    ... Well, except that arrays tend to be much larger than pointers, and the ... An array is a contiguous region of memory containing N elements of M ... indexing vs. a loop). ...
    (comp.arch.embedded)
  • Re: How to make (ptr + len) > lim safe?
    ... Meaning I use ptr < lim where ptr and lim are both pointers ... However, if ptr and lim both point into or one past the end of the same array, and if ptr < lim, then lim-ptr has to be positive, and that is something the standard does say. ... Not directly, but by inference from what it says about the binary '-' operator and the '<' operator, when acting on pointers: ...
    (comp.lang.c)