- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How to declare a one dimensional array that can be passed to a function, and in function it is resized and returned. I was trying to adapt an example in docs for MOVE_ALLOC:
program fmalloc ! This program uses MOVE_ALLOC to make an allocated array X bigger and ! keep the old values of X in the variable X. Only one copy of the old values ! of X is needed. implicit none ! Variables integer :: I, N = 2 real, allocatable :: X(:), Y(:) ! Body of fmalloc allocate (X(N), Y(2*N)) ! Y is twice as big as X X = (/(I,I=1,N)/) ! put "old values" into X Y = -1 ! put different "old values" into Y print *, ' allocated of X is ', allocated (X) print *, ' allocated of Y is ', allocated (Y) print *, ' old X is ', X print *, ' old Y is ', Y Y (1:N) = X ! copy all of X into the first half of Y ! this is the only copying of values required print *, ' new Y is ', Y call move_alloc (Y, X) ! X is now twice as big as it was, Y is ! deallocated, the values were not copied from Y to X print *, ' allocated of X is ', allocated (X) print *, ' allocated of Y is ', allocated (Y) print *, ' new X is ', X !faX(X) not implemented !print *, ' new X is ', X end program fmalloc
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something that seems OK:
!**************************************************************************** ! ! PROGRAM: fmalloc ! ! PURPOSE: Entry point for the console application. ! !**************************************************************************** module farray contains subroutine faX(aX) real, allocatable, intent(inout) :: aX(:) integer:: aisize integer :: I integer :: aishape(1) real, allocatable :: aY(:) ! aishape=SHAPE(aX) !N=aishape(1) aisize=SIZE(aX) allocate (aY(2*aisize)) ! Y is twice as big as X !X = (/(I,I=1,N)/) ! put "old values" into X aY = -2 ! put different "old values" into Y print *, ' allocated of aX is ', allocated (aX) print *, ' allocated of aY is ', allocated (aY) print *, ' old aX is ', aX print *, ' old aY is ', aY aY (1:aisize) = aX ! copy all of X into the first half of Y ! this is the only copying of values required print *, ' new aY is ', aY call move_alloc (aY, aX) ! X is now twice as big as it was, Y is ! deallocated, the values were not copied from Y to X print *, ' allocated of aX is ', allocated (aX) print *, ' allocated of aY is ', allocated (aY) print *, ' new aX is ', aX aisize=SIZE(aX) end subroutine faX end module farray ! program fmalloc use farray ! This program uses MOVE_ALLOC to make an allocated array X bigger and ! keep the old values of X in the variable X. Only one copy of the old values ! of X is needed. implicit none ! Variables integer :: I integer :: N = 2 real, allocatable :: X(:), Y(:) ! Body of fmalloc allocate (X(N), Y(2*N)) ! Y is twice as big as X X = (/(I,I=1,N)/) ! put "old values" into X Y = -1 ! put different "old values" into Y print *, ' allocated of X is ', allocated (X) print *, ' allocated of Y is ', allocated (Y) print *, ' old X is ', X print *, ' old Y is ', Y Y (1:N) = X ! copy all of X into the first half of Y ! this is the only copying of values required print *, ' new Y is ', Y call move_alloc (Y, X) ! X is now twice as big as it was, Y is ! deallocated, the values were not copied from Y to X print *, ' allocated of X is ', allocated (X) print *, ' allocated of Y is ', allocated (Y) print *, ' new X is ', X call faX(X) print *, ' new X is ', X end program fmalloc
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Previous no check for rank1,
In c++ the idea was like:
#include "pch.h" #include <iostream> #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #define AITEST (0x20) int resize(int** ppai, int ilen, double drsz) { int* pai = *ppai; int icopy; int iret = (int)(double(ilen) * drsz); int* aitemp = new int[iret]; if (iret > ilen)icopy = ilen; else icopy = ilen; for (int i = 0; i < icopy; i++) *(aitemp+i) = *(pai+i); if (icopy < iret)for (int i = icopy; i < iret; i++) *(aitemp + i) = i; int* pai_old = pai; *ppai = aitemp; delete[] pai_old; return iret; } int main(int argc, char *argv[]){ int iaisz=AITEST; int* ai0 = new int[iaisz]; for (int i = 0; i < iaisz; i++) *(ai0+i) = i; iaisz = resize(&ai0, iaisz, 1.5); delete[] ai0; bool bLeak_= _CrtDumpMemoryLeaks(); return 0; }
:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you have a question? You use of MOVE_ALLOC here is the classic use case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was looking for review, as in "there is a better way" or how this does something wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, this is the classic method of performing this task.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mwindham,
In your code example in #2, you should be aware that the extended portion of the move-alloc'd array is uninitialized. IOW do not consider these values 0.0 or an arbitrary value that is not a signaling NaN. If this is a potential issue then you will have to initialize these cells to your preference value (which, if you desire, may hold a value you select as never been used such as a subnormal, or TINY or HUGE).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for noting initialization omission.

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