By Pureferret


2011-12-05 11:11:08 8 Comments

My program is running though 3D array, labelling 'clusters' that it finds and then doing some checks to see if any neighbouring clusters have a label higher than the current cluster. There's a second array that holds the 'proper' cluster label. If it finds that the nth adjoining cluster is labelled correctly, that element is assigned to 0, otherwise is assigns it to the correct label (for instance if the nth site has label 2, and a neighbour is labeled 3, the 3rd element of the labelArray is set to 2). I've got a good reason to do this, honest!

All I want is to be able to assign the nth element of the labelArray on the fly. I've looked at allocatable arrays and declaring things as labelArray(*) but I don't really understand these, despite searching the web, and StackOverflow.

So any help on doing this would be awesome.

3 comments

@Vladimir F 2011-12-05 11:46:27

If you declare an array allocatable, you use deffered shape in the form real,

allocatable :: labelArray(:,:)

, or

real,dimension(:,:),allocatable :: labelArray

with number of double colons meaning rank (number of your indexes) of your array.

If the array is unallocated you use

 allocate(labelarray(shapeyouwant))

with the correct number of indexes. For example allocate(labelarray(2:3,-1:5)) for array with indexes 2 to 3 in demension 1 and -1 to 5 in dimension 2.

For change of dimension you have to deallocate the array first using

deallocate(labelArray)

To reallocate an allocated array to a new shape you first need to allocate a new array with the new shape, copy the existing array to the new array and move the reference of the old array to the new array using move_alloc().

  call allocate(tmp(size_old+n_enlarge))
  tmp(1:size_old) = array(1:size_old)
  call move_alloc(tmp, array)

The old array is deallocated automatically when the new array reference is moved by move_alloc().


Fortran 95 deallocates arrays automatically, if they fall out of scope (end of their subroutine for example).

Fortran 2008 has a nice feature of automatic allocation on assignment. If you say array1=array2 and array1 is not allocated, it is automatically allocated to have the correct shape.

@Pureferret 2011-12-05 12:50:47

So is this a valid statement? allocate(labelArray(size(labelArray)+1)) All I want is to increase the size when I add on an element.

@Vladimir F 2011-12-05 12:55:44

No, it is not possible. You can not change allocated dimension of the array. It would be to complicated. The program would have to make a copy anyway quite possibly. You have to 1)make a new bigger array and copy to it, or 2) make a copy of your array, deallocate it, allocate it bigger and copy the saved values back. If your compiler supports it, you can use move_alloc, instead of copy, then you don't have to deallocate your array, just allocate it bigger and copy the saved values back.

@Vladimir F 2018-06-06 12:24:37

Actually, too complicated... there is realloc in C, but Fortran just doesn't have it.

@Pureferret 2018-06-06 14:18:25

That must be the record for the longest time between two parts of comment.

@Mateen Ulhaq 2019-02-05 11:12:23

I'm going to set a date on my calendar to come back to this answer in 10 years to beat this record. Once upon a time, there lived a person who didn't finish their sentences until

@Alvaro Fernandez 2014-06-11 13:45:57

Late comment... check Numerical Recipes for Fortran 90. They implemented a nice reallocate function that was Fortran 90 compliant. Your arrays must be pointer attributed in this case, not allocatable attributed.

The function receives the old array and desired size, and returns a pointer to the new resized array.

If at all possible, use Fortran 95 or 2003. If 2003 is impossible, then 95 is a good compromise. It provides better pointer syntax.

@M. S. B. 2011-12-05 11:50:41

Here is a Stack Overflow question with some code examples showing several ways of using Fortran allocatable arrays: How to get priorly-unkown array as the output of a function in Fortran: declaring, allocating, testing for being already being allocated, using the new move_alloc and allocation on assignment. Not shown there is explicit deallocation, since the examples are using move_alloc and automatic deallocation on exit of a procedure.

P.S. If you want to repeatedly add one element you should think about your data structure approach. Adding one element at a time by growing an array is not an efficient approach. To grow an array from N elements to N+1 in Fortran will likely mean creating a new array and copying all of the existing elements. A more appropriate data structure might be a linked list. You can create a linked list in Fortran by creating a user-defined type and using pointers. You chain the members together, pointing from one to the next. The overhead to adding another member is minor. The drawback is that it is easiest to access the members of the list in order. You don't have the easy ability of an array, using indices, to access the members in any order.

Info about linked lists in Fortran that I found on the web: http://www-uxsup.csx.cam.ac.uk/courses/Fortran/paper_12.pdf and http://www.iag.uni-stuttgart.de/IAG/institut/abteilungen/numerik/images/4/4c/Pointer_Introduction.pdf

@Pureferret 2011-12-05 13:31:56

So looking at what @Vladimir wrote, and your link, is this acceptable code? allocate(temp(size(labelArray)+1))// temp(:size(labelArray))=labelArray// call move_alloc(temp,labelArray)

@M. S. B. 2011-12-05 13:50:52

That looks correct. If the array size is large it may be inefficient because of the copy caused by the assignment statement.

@Pureferret 2011-12-05 14:01:32

Ok, When I ran it with an oversized array there weren't that many actual elements. I'm restricted to using fortran90 however, and I didn't think it had pointers?

@M. S. B. 2011-12-05 14:20:41

Fortran 90 has pointers. If you are limited to Fortran 90 (that's a long time ago!), then you won't be able to use move_alloc since that is a Fortran 2003 addition. The replacement is to deallocate labelArray, allocate labelArray to the new size, assign to LabelArray, then deallocate temp.

@Pureferret 2011-12-05 14:41:21

I put in the move_alloc code and the compile didn't shout at me. I've put in the deallocation code now and it still doesn't shout. I need to fix an array-assignment issue before I know it worked though.

@Pureferret 2011-12-05 15:14:39

I'm now getting a segfault at a seemingly arbitrary line of code, which doesn't relate to the piece of code with allocation and deallocation. I'm a little confused as to why this would be. If I move the allocation/deallocation it segfaults on the deallocation line: deallocate(labelArray). Any idea why?

@milancurcic 2011-12-05 15:59:26

@Pureferret Post code sample please? Segfault on deallocate line probably means you are trying to deallocate some array/index which has not been allocated.

@Pureferret 2011-12-05 17:09:43

I've spotted what's going wrong; yes I haven't allocated labelArray before deallocating. Will go fix. Edit: It works now. Thanks everyone!

Related Questions

Sponsored Content

34 Answered Questions

[SOLVED] Create ArrayList from array

41 Answered Questions

[SOLVED] Loop through an array in JavaScript

88 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6153540 View
  • 7681 Score
  • 88 Answer
  • Tags:   javascript arrays

47 Answered Questions

[SOLVED] How to check if an object is an array?

47 Answered Questions

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

28 Answered Questions

[SOLVED] How do I determine whether an array contains a particular value in Java?

  • 2009-07-15 00:03:21
  • Mike Sickler
  • 1895227 View
  • 2197 Score
  • 28 Answer
  • Tags:   java arrays

16 Answered Questions

[SOLVED] How to insert an item into an array at a specific index (JavaScript)?

30 Answered Questions

[SOLVED] How to append something to an array?

18 Answered Questions

[SOLVED] How do I empty an array in JavaScript?

  • 2009-08-05 09:08:39
  • akano1
  • 2438958 View
  • 2198 Score
  • 18 Answer
  • Tags:   javascript arrays

Sponsored Content