I have the following structures defined:
point_str={loop_point, x:0d, y:0d}
loop_time_str={loop_time_struct, points:ptr_new(/allocate_heap), loop_id:0d, time:0d}
loop_str={loop_struct,time_series:replicate(loop_time_str, num_images), loop_id:0d}
Points is an array and because the size of points varies I understand it needs to be a pointer.
Later on I create a new variable:
curr_loop_intime = {loop_time_struct}
I then populate the values.
FOR POINT=0,n_elements(IND)-1 DO BEGIN
points_arr[POINT].x = X(IND[POINT])
points_arr[POINT].y = Y(IND[POINT])
ENDFOR
I then try to assign the points array to the loop by doing:
*(curr_loop_intime.points)=ptr_new(points_arr)
But this line gives me the error:
% Unable to dereference NULL pointer: <POINTER (<NullPointer>)>.
Does anyone have any suggestions?
It seems like you are trying to assign the pointer-to-points_arr to the dereferenced pointer curr_loop_intime.points [ by surrounding with *() ]. Since curr_loop_intime.points has not previously been assigned to point to anything, IDL is unable to dereference it, and hence the error is thrown.
Try removing the *() from your assignment statement, so that you are assigning the pointer-to-points_arr to the .points structure member, which is declared as a variable of type pointer.
Hope this helps.
Related
Suppose I have a pointer to a polymorphic object:
TYPE, ABSTRACT:: ab
ENT TYPE
TYPE, EXTENDS(ab):: co
INTEGER:: i
ENT TYPE
Class(ab), POINTER:: foo
How do I initialize the object pointed by foo to be a co object, in the executable part of the code? I am thinking of something like
foo => co(1) ! WRONG
but this is wrong.
Pointers can only be initialized with a target with the save attribute or with null(). If you mean the initialization during compilation in the declaration part.
In the executable part of code you can certainly make the pointer to point to an object. But you need an actual object with the target attribute or you need to make an anonymous target using the allocate() statement.
co(1) is an expression or a value result of an expression. You cannot point to it, it does not have the pointer attribute. You could allocate an anonymous target with this value
allocate(foo, source=co(1))
Consider using allocatable instead of a pointer, they should be strongly preferred. If you could use allocatable, it is as simple as
foo = co(1)
thanks to the automatic (re)allocation in the assignment.
When I dynamically create a pointer to a type and then pass it in to an unmarshalling function, it seems to be written correctly, in theory:
x := reflect.New(structType)
decode(x)
However, when you print x, it looks like the zero value of the type. The type is definitely correct and expected.
On the other hand, when I create the type and pass a pointer to it, directly, it works fine:
directoryEntry := DirectoryEntry{}
decode(&directoryEntry)
The contents are set correctly by decode() and, when printed, are correct.
So, it seems like I must be passing a value of the type to decode() and not a reference?
Can someone point out what I must be missing? A number of Google queries didn't help, and it seems like I must be missing something small.
reflect.New() returns you a pointer to a value of the passed type, but the returned pointer is wrapped in a reflect.Value struct!
Use Value.Interface() to "unwrap" it, and have a pointer as an interface{} which you can pass to decode():
x := reflect.New(structType)
p := x.Interface()
decode(p)
When you print a reflect.Value, you often won't see a difference, because the reflect.Value type is treated special; quoting from Value.String():
The fmt package treats Values specially. It does not call their String method implicitly but instead prints the concrete values they hold.
I have a problem assigning a pointer to a structure, to a pointer to a structure.
I use gfortran 4.6.3, and the name of the file is test_pointer_struct.f08 so I am using the Fortran 2008 standard (as supported by gfortran 4.6.3).
Hera comes the code:
PROGRAM test_pointer_struct
type tSmall
integer :: a
double precision :: b
end type tSmall
type tBig
integer :: h
type(tSmall), pointer :: member_small
end type tBig
type(tBig) :: var_big
type(tSmall), pointer :: var_small(:)
! We get an array of pointers to the small structure
allocate(var_small(3))
! Also allocate the member_small strucutre (not an array)
allocate(var_big%member_small)
var_big%member_small%a = 1
var_big%member_small%b = 2.0
! Now we want an element of the var_samall array of pointers, to point to the member_small in member_big
var_small(1) => var_big%member_small ! <- I get a compilation error here
! And dissasociate the member_small (we still maintain access to memory space through var_small(1)
var_big%member_small => NULL()
END PROGRAM test_pointer_struct
When I complie this, I get the following error:
Error: Se esperaba una especificación de límites para 'var_small' en (1)
Which could be translated as
Error: Limit specification expected for 'var_small' at (1)
What does this error mean?. What am I doing wrong?
Thank you very much in advance.
Fortran doesn't really do arrays of pointers. Your declaration
type(tSmall), pointer :: var_small(:)
doesn't define var_small to be an array of pointers to things of type tsmall; rather it defines it to be a pointer to an array of things of type tsmall.
When I compile your code Intel Fortran gives the rather more helpful error message
The syntax of this data pointer assignment is incorrect: either 'bound
spec' or 'bound remapping' is expected in this context.
which takes us to R735 in the Fortran 2003 standard. The compiler tries to parse var_small(1) not, as you wish, as a reference to the first element in an array of pointers but to either a bounds-spec-list or a bounds-remapping-list. The expression does not have the right syntax for either and the parse fails.
So that deals with the question of what the error means. What do you do about it ? That depends on your intentions. The usual suggestion is to define a derived type, along these lines
type myptr
type(tsmall), pointer :: psmall
end type myptr
and then use an array of those
type(myptr), dimension(:), allocatable :: ptrarray
Personally I've never liked that approach and have never needed to use it (I write very simple programs). I expect that with Fortran 2003 there are better approaches too but without knowing your intentions I hesitate to offer advice.
I created an array like this one:
type coef_list is array(Integer range 0..50) of Integer;
But the message appears when I call this function:
t:= times(r,q); --that multiply two polynoms.
Why? I need a dynamic array? with Ada.Vectors but how to used it? if there is any simple example to guide me, please share? Thx
Ada procedures (and similar for functions) require this structure:
procedure Foo is
-- declarations goes here
begin
-- code goes here
end Foo;
In your code, both polynomials and Main is missing the begin.
You have also put declarations (value1 : integer := 1; etc) after begin in print_polynoms, which is illegal.
Other problems with your code:
You redefine the built-in type String.
The type zero is not defined anywhere.
The type String_Pointer is not defined anywhere.
This syntax makes no sense: type Polynom is new Integer(p,p1,p2,p3,p4,q,q1,q2); And the type Polynom is never used. Why declare it?
The variable zero is not defined anywhere.
Why have an inner procedure Main here? It does nothing anyway. And is never called. Probably better to move print_polynoms out of Main, as an inner function of polynomials directly.
The polynomials procedure does nothing, print_polynoms will never be called.
Also, the code you pasted seems to not be the same as the code you tried to compile. (main is not declared at line 9)
Given below is some code in ada
with TYPE_VECT_B; use TYPE_VECT_B;
Package TEST01 is
procedure TEST01
( In_State : IN VECT_B ;
Out_State : IN OUT VECT_B );
function TEST02
( In_State : IN VECT_B ) return Boolean ;
end TEST01;
The TYPE_VECT_B package specification and body is also defined below
Package TYPE_VECT_B is
type VECT_B is array (INTEGER range <>) OF BOOLEAN ;
rounded_data : float ;
count : integer ;
trace : integer ;
end TYPE_VECT_B;
Package BODY TYPE_VECT_B is
begin
null;
end TYPE_VECT_B;
What does the variable In_State and Out_State actually mean? I think In_State means input variable. I just get confused to what actually Out_State means?
An in parameter can be read but not written by the subprogram. in is the default. Prior to Ada 2012, functions were only allowed to have in parameters. The actual parameter is an expression.
An out parameter implies that the previous value is of no interest. The subprogram is expected to write to the parameter. After writing to the parameter, the subprogram can read back what it has written. On exit the actual parameter receives the value written to it (there are complications in this area!). The actual parameter must be a variable.
An in out parameter is like an out parameter except that the previous value is of interest and can be read by the subprogram before assignment. For example,
procedure Add (V : Integer; To : in out Integer; Limited_To : Integer)
is
begin
-- Check that the result wont be too large. This involves reading
-- the initial value of the 'in out' parameter To, which would be
-- wrong if To was a mere 'out' parameter (it would be
-- uninitialized).
if To + V > Limited_To then
To := Limited_To;
else
To := To + V;
end if;
end Add;
Basically, every parameter to a function or procedure has a direction to it. The options are in, out, in out (both), or access. If you don't see one of those, then it defaults to in.
in means data can go into the subroutine from the caller (via the parameter). You are allowed to read from in parameters inside the routine. out means data can come out of the routine that way, and thus you are allowed to assign values to the parameter inside the routine. In general, how the compiler accomplishes the data passing is up to the compiler, which is in accord with Ada's general philosophy of allowing you to specify what you want done, not how you want it done.
access is a special case, and is roughly like putting a "*" in your parameter definition in Cish languages.
The next question folks usually have is "if I pass something large as an in parameter, is it going to push all that data on the stack or something?" The answer is "no", unless your compiler writers are unconsionably stupid. Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine. Again, you tell Ada what you want done, it figures out the most efficient way to do it.