This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Linked list recursive reverse
I searched my question on SO and got a link
recursion stack trace
I din't understand How the head_ref is Pointing to 4 there?
Could anyone help me to understand this?
ok, first of all, it's 6 am here, and i couldn't sleep all night ... so this might be bullshit ;) ... but here we go:
the "magic" happens at recursiveReverse(&rest); ... the & says that the parameter is the address of rest ... since rest itself is a pointer, our param is a pointer to a pointer ...
when the function has finished, the pointer has been changed, and points to the first element of the reversed sub-list (which is the 4-Node) ...
EX:
so let's say we have our list 1 -> 2 -> 3 -> 4 and have called recursiveReverse(struct node** head_ref) with a pointer to a pointer to the 1-node as the head_ref parameter
so let's say head_ref is at a certain address (which i call A)
head_ref is a pointer to a pointer ... so the value at the address A is another address (let's call that B)
so the "thing" that is stored at B is a pointer ... so the value at B is also an address (let's call that address C)
finally the "thing" stored at C is our struct ...
now with this in mind, we make our first recursive call to recursiveReverse(struct node** head_ref) ... this time our parameter is &rest ... &rest is a pointer to a pointer to the 2-node...
let's have a closer look ... the value of &rest is an address ... (hard to guess, we call that D) ... the value at D is an address (the address of the 2-node) which we call E
after the recursive call has finished, the sub-list 2 -> 3 -> 4 has been reversed (4 -> 3 -> 2), and one of our addresses has been updated with a new value ... D has been updated, and no longer holds the address E, but the address of the 4-node (call that F if you want ...)
so now, we have the pointer "first" pointing to the 1-node which has its next-pointer still pointing at the 2-node... so with first->next->next = first, we correct the 2-nodes "next" pointer, to point at the 1-node ...
since the 1-node shall no longer point to the 2-node, we have first->next=NULL and now the complete list has been reversed ...
since we have no return value, we return our reversed list by the pointer to pointer parameter head_ref ... with *head_ref = rest
rest is a pointer ... it's located at address D ... the current value at D is F (address of the 4-node)
so we write the value of D (which is F, the address of the 4-node) to the Address B (which is *head_ref)
and that is how the pointer to the 4-node is returned
Related
My erroneous code snippet and compiler error info:
// code snippet 1:
0 fn main() {
1 let mut x: Box<i32> = Box::new(4);
2 let r: &Box<i32> = &x;
3 *x = 8;
4 println!("{}", r);
5 }
// compiler error info:
error[E0506]: cannot assign to `*x` because it is borrowed
--> src/main.rs:3:4
|
2 | let r = &x;
| -- borrow of `*x` occurs here
3 | *x = 8;
| ^^^^^^ assignment to borrowed `*x` occurs here
4 | println!("{}", r);
| - borrow later used here
For more information about this error, try `rustc --explain E0506`.
The following code won't compile, which makes quite senses to me cause we cannot invalidate the reference r .
// code snippet 2:
0 fn main() {
1 let mut x: i32 = 0;
2 let r: &i32 = &x;
3 x = 1;
4 println!("{}", r);
5 }
But the compiler error info of code snippet1 doesn't make too much sense to me.
x is a pointer on the stack pointing to a heap memory segment whose contents is 4 , reference r only borrows x (the pointer not the heap memory segment) , and in line 3 *x = 8; , what we did here is to alter the memory on the heap (not the pointer on the stack) . Change happens on the heap , while reference is only relevant to the stack, they do not interrelate.
This question is kind of picking a quarrel, but I do not mean to argue for the sake of argument.
If you found my question irregular, feel free to point it out :)
Change happens on the heap , while reference is only relevant to the stack, they do not interrelate.
That does not matter, because the type system doesn't work with that "depth" of information.
As far as it's concerned, borrowing x is borrowing the entirety of x up to any depth, and so any change anywhere inside x is forbidden.
For type checking purposes, this is no different than if x were a Box<Vec<_>>, and r were be actively used for iteration, leading any update to the inner vector to possibly invalidate the iterator.
(also type-wise *x = 8 does require first taking a unique reference to the box itself, before "upgrading" it to a unique reference to the box' content, as you can see from the trait implementation)
Rust's entire borrowing model enforces one simple requirement: the contents of a memory location can only be mutated if there is only one pointer through which that location can be accessed.
In your case, the heap location that you're trying to mutate can be accessed both through x and through r—and therefore mutation is denied.
This model enables the compiler to perform aggressive optimisations that permit, for example, the storage of values reachable through either alias in registers and/or caches without needing to fetch again from memory when the value is read.
The semantics of * is determined by two traits:
pub trait Deref {
type Target: ?Sized;
fn deref(&self) -> &Self::Target;
}
or
pub trait DerefMut: Deref {
fn deref_mut(&mut self) -> &mut Self::Target;
}
In your case, when you write *x = 8 Rust compiler expands the expression into the call
DerefMut::deref_mut(&mut x), because Box<T> implements Deref<Target=T> and DerefMut. That is why in the line *x = 8 mutable borrowing of x is performed, and by orphan rule it can't be done, because we've already borrowed x in let r: &Box<i32> = &x;.
I just found a great diagram from Programming Rust (Version 2), which really answers my question quite well:
In the case of my question, when x is shared-referenced by r, everything in the ownership tree of x (the stack pointer and the heap memory segment) becomes read-only.
I knew that the Stack Overflow community does not like pictures, but this diagram is really great and may help someone who will find this question in the future:)
I have a grammar that looks like:
A:
myField=[B]
B:
C | D | E
I have a function that gets A (let's say a) as a parameter and I want to access C, for example.
I did a.myField that returns a B object (let's say b). Than I used
EcoreUtil2.getAllContentsOfType(b,C) - but it returns an empty list.
Maybe the reason is that B is not really parsed again, but cross-referenced. If so, is there any function that allows me to access C/D/E in the above example?
Thank you.
Update
Apparently b is null, so of course getAllContentsOfType() returns an empty list. How do I access B (which is cross-referenced from A)?
Had to check that a.myField isn't null.
Ex : Function Implementation:
facto(x){
if(x==1){
return 1;
}
else{
return x*facto(x-1);
}
in more simple way lets take a stack -->
returns
|2(1)|----> 2(1) evaluates to 2
|3(2)|----> 3(2)<______________| evaluates to 6
|4(3)|----> 4(6)<______________| evaluates to 24
|5(4)|----> 5*(24)<____________| evaluates to 120
------ finally back to main...
when a function returns in reverse manner it never knows what exactly is behind it? The stack have activation records stored inside it but how they know about each other who is popped and who is on top?
How the stack keeps track of all variables within the function being
executed? Besides this, how it keeps track of what code is executed
(stackpointer)? When returning from a function call the result of that
function will be filled in a placeholder. By using the stackpointer
but how it knows where to continue executing code? These are the
basics of how the stack works I know but for recursion I don't
understand how it exactly works??
When a function returns its stack frame is discarded (i.e the complete local state is pop-ed out of the stack).
The details depend on the processor architecture and language.
Check the C calling conventions for x86 processors: http://en.wikipedia.org/wiki/X86_calling_conventions, http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames and search for "PC Assembly Language" by Paul A. Carter (its a bit outdated but it has a good explanation of C and Pascal calling conventions for the ia32 architecture).
In C in x86 processors:
a. The calling function pushes the parameters of the called function to the stack in reverse order and then it pushes the pointer to the return address.
push -6
push 2
call add # pushes `end:` address an then jumps to `add:` (add(2, -6))
end:
# ...
b. Then the called function pushes the base of the stack (the ebp register in ia32) (it is used to reference local variables in the caller function).
add:
push ebp
c. The called function sets ebp to the current stack pointer (this ebp will be the reference to access the local variables and parameters of the current function instance).
add:
# ...
mov ebp, esp
d. The called function reserves space in the stack for the local (automatic) variables subtracting the size of the variables to the stack pointer.
add:
# ...
sub esp, 4 # Reserves 4 bytes for a variable
e. At the end of the called function it sets the stack pointer to be ebp (i.e frees its local variables), restores the ebp register of the caller function and returns to the return address (previously pushed by the caller).
add:
# ...
mov esp, ebp # frees local variables
pop ebp # restores old ebp
ret # pops `end:` and jumps there
f. Finally the caller adds to the stack pointer the space used by the parameters of the called function (i.e frees the space used by the arguments).
# ...
end:
add esp, 8
Return values (unless they are bigger than the register) are returned in the eax register.
I would like to get the address of an array pointer. The prototype codes are as following:
program main
implicit none
type foo
integer, allocatable :: i(:)
integer j
end type
type(foo) a
integer, pointer :: ai(:)
ai => a%i
print *, "The address of a is ", loc(a)
print *, "The address of a%i is", loc(ai) ! <--- I expect the same address as a.
end program main
My final target is to get the address of a with type(foo) through the address of array pointer ai, since i is the first part of type(foo).
Thanks in advance!
Li
Fortran doesn't guarantee that the first item of a user-defined the same address as that user-defined type. Maybe there is a header before the items. Maybe there is some padding. Maybe the compiler stores the items in a different order. Maybe different compilers do it differently. None of this is specified. So your expectation may not occur. There is little need in Fortran for addresses. What are you trying to do? If you are interfacing to C, the ISO_C_Binding provides C_LOC.
EDIT in response to the comment. If your goal is to simplifying the variable name by omitting the leading "a %", you can use a pointer to create an alternative variable that accesses the same storage. You don't have to try to get past the language with pointers. Example:
program main
implicit none
type foo
integer, pointer :: i(:)
integer j
end type
type(foo) a
integer, pointer :: ai(:)
allocate ( a%i (5) )
a%i = [ 2, 5, 1, 3, 9 ]
ai => a%i
write (*, '( "a%i=", 5(2X,I2) )' ) a%i
write (*, '( "ai=", 5(2X,I2) )' ) ai
end program main
Output is:
a%i= 2 5 1 3 9
ai= 2 5 1 3 9
You can't, not using standard Fortran anyway.
Note that your expectations are misplaced.
loc is an extension. What it does is processor specific, but typically it will give you an integer representation of the address of the data object that the argument represents. (The F2003 standard's C_LOC is roughly equivalent.). In this case, the data object is an allocatable array. In all processors that I am aware of the storage for that array is not in the storage for the object of derived type that hosts the allocatable component. The derived type object simply contains a descriptor that describes where the array is stored (and how big it is, etc), not storage for the array itself.
I'm working on a p2p app that uses hash trees.
I am writing the hash tree construction functions (publ/4 and publ_top/4) but I can't see how to fix publ_top/4.
I try to build a tree with publ/1:
nivd:publ("file.txt").
prints hashes...
** exception error: no match of right hand side value [67324168]
in function nivd:publ_top/4
in call from nivd:publ/1
The code in question is here:
http://github.com/AndreasBWagner/nivoa/blob/886c624c116c33cc821b15d371d1090d3658f961/nivd.erl
Where do you think the problem is?
Thank You,
Andreas
Looking at your code I can see one issue that would generate that particular exception error
publ_top(_,[],Accumulated,Level) ->
%% Go through the accumulated list of hashes from the prior level
publ_top(string:len(Accumulated),Accumulated,[],Level+1);
publ_top(FullLevelLen,RestofLevel,Accumulated,Level) ->
case FullLevelLen =:= 1 of
false -> [F,S|T]=RestofLevel,
io:format("~w---~w~n",[F,S]),
publ_top(FullLevelLen,T,lists:append(Accumulated,[erlang:phash2(string:concat([F],[S]))]),Level);
true -> done
end.
In the first function declaration you match against the empty list. In the second declaration you match against a list of length (at least) 2 ([F,S|T]). What happens when FullLevelLen is different from 1 and RestOfLevel is a list of length 1? (Hint: You'll get the above error).
The error would be easier to spot if you would pattern match on the function arguments, perhaps something like:
publ_top(_,[],Accumulated,Level) ->
%% Go through the accumulated list of hashes from the prior level
publ_top(string:len(Accumulated),Accumulated,[],Level+1);
publ_top(1, _, _, _) ->
done;
publ_top(_, [F,S|T], Accumulated, Level) ->
io:format("~w---~w~n",[F,S]),
publ_top(FullLevelLen,T,lists:append(Accumulated,[erlang:phash2(string:concat([F],[S]))]),Level);
%% Missing case:
% publ_top(_, [H], Accumulated, Level) ->
% ...