- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I am trying to use the routine ReAllocbut I get the following error.
What am I doing wrong?
subroutine TryReAlloc
real,allocatable::B(:)
integer::j
real::c
integer::j
real::c
c=1.34
do j=1,10
call ReAlloc (B,j)
B(j)=c*j
end do
call ReAlloc (B,j)
B(j)=c*j
end do
end subroutine TryReAlloc
!--------------------------
subroutine ReAlloc (A,n)
! A array
! n new size
! A array
! n new size
real,allocatable::A(:)
integer::n,nOld
real,allocatable::Temp(:)
nOld=size(A)
if (nOld > n) RETURN
allocate (Temp(nOld))
Temp=A
Deallocate (A)
Allocate (A(n))
A(1:nOld)=Temp
end subroutine ReAlloc
integer::n,nOld
real,allocatable::Temp(:)
nOld=size(A)
if (nOld > n) RETURN
allocate (Temp(nOld))
Temp=A
Deallocate (A)
Allocate (A(n))
A(1:nOld)=Temp
end subroutine ReAlloc
Warning: In the call to REALLOC, actual argument #1 does not match the type and kind of the corresponding dummy argument.
call ReAlloc (B,j)
call ReAlloc (B,j)
Thanks,
David
링크가 복사됨
6 응답
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
You need an explicit interface to call a routine which has a deferred-shape (:) argument.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Thanks, I have got it working now.
I am trying to repicate the Visual Basic redim preserve command.
I have found that the method of using the ReAlloc routine takes long time for a large array.
Repeating the loop 100 time takes 0.000 secs, 1,000 times takes 0.08 secs, 10,000 times takes 8.4 secs, 100,000 times - I gave up waiting.
Is there a more efficient way of doing this?
David
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Not at present. Fortran 2003 offers a way of doing a "realloc" on allocatables. You would have a bit better luck using POINTER as you could just move pointers around and just move the data once and not twice.
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
David,
You can speed it up using C code (or even, an equivalent Fortran code), by directly manipulating Fortran array descriptor. Basically, the F2000 MOVE_ALLOC does only one allocation instead of two, by means of having two pieces of allocated memory -- the old one and the new one -- simultaneously. Here's a sketch, which reusessome codefrom thread:
Code:
void move_alloc(CVF_1D_DESCRIPTOR* A, int iSizeSingleElement,
int iNewArraySize)
{
void* lpOldAddress;
lpOldAddress = A->lpAddress;
A->lpAddress = malloc(iNewArraySize*iSizeSingleElement);
// Copy the old contents into new location
if (A->iAllocated)
{
memcpy(lpOldAddress, A->lpAddress, A->Dim1.iExtent * iSizeSingleElement);
// kill the old allocation
free(lpOldAddress);
}
A->Dim1.iExtent = iNewArraySize;
//Fill in the rest of A appropriately
}Instead of malloc/memcpy/free you can use native Windows APIs or whatever. Note, however, that you have to use same allocators as were used to allocate the original array, meaning that you cannot e.g. free() memory which was not allocated with malloc() but e.g. with ALLOCATE (unless you happen to know which API is used by ALLOCATE internally). Thus, you should probably write your own (de)allocation routines in C, using the same malloc/free as used in move_alloc above.
Hope this helps,
Jugoslav
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Alas, only temporarily :-( -- they merged some holidays so I got an extended weekend off. I'll be definitely back only in mid-August.
Regards
Jugoslav