functions returning pointers
Author |
Message |
Mike F #1 / 4
|
functions returning pointers
Two questions: 1) Is it acceptable practice to define a function which returns a pointer to a variable local to that function? i.e.: function foo(x,y : sometype) : somepointertype; var z : sometype; begin z := whatever you want here;
end; This seems to work OK, but I can't see if it is strictly legal. 2) Assuming the above is OK, is there a work-around for the problem that occurs when you define a second function as: function bar(p,q : somepointertype) : anothertype; begin whatever you want to do here end; and call it using returns from foo as arguements?: bar(foo(w,x),foo(y,z)); This doesn't work as the first pointer appears to be corrupted when foo is called the second time. Any obvious solutions? -- Mike Fee
Industrial Research Limited
|
Wed, 18 Jun 1902 08:00:00 GMT |
|
|
Jochen Heyla #2 / 4
|
functions returning pointers
Quote: >Two questions: >1) Is it acceptable practice to define a function which returns a >pointer to a variable local to that function? i.e.: >function foo(x,y : sometype) : somepointertype; >var > z : sometype; >begin > z := whatever you want here;
>end; >This seems to work OK, but I can't see if it is strictly legal.
Doing this means that you are returning a pointer to an item on the stack that has already been released. z is valid only during the function itself, being a local variable. Generally, this works until the next function call or any other manipulation of the stack but you should not ever count on it working. Quote: >2) Assuming the above is OK, is there a work-around for the problem that >occurs when you define a second function as: >function bar(p,q : somepointertype) : anothertype; >begin > whatever you want to do here >end; >and call it using returns from foo as arguements?: >bar(foo(w,x),foo(y,z)); >This doesn't work as the first pointer appears to be corrupted when foo is >called the second time. Any obvious solutions?
This does not work because of the reasons stated above. There are several alternatives: 1.Create, using new or getmem, space on the heap for the function result. The disadvantage is that you will need to free the memory elsewhere, ie in your function bar. 2.Create globals for the results Disadvantage is the use of globals as well as foo needing to know which global to use 3.Create the space outside of foo and pass it in. This is what the pchar functions want and is, in some sense, the most elegant. However, it is a bit strange to pass in the parameter that you want to return. 4.If the type of pointer foo returns points to a variable of less than 256 bytes, you can have foo return it as a string and do away with the pointer that foo returns using typecasting. A bit strange and limited to small records but it does work. Does this help? Jochen
|
Wed, 18 Jun 1902 08:00:00 GMT |
|
|
Duncan Murdo #3 / 4
|
functions returning pointers
Quote:
>Two questions: >1) Is it acceptable practice to define a function which returns a >pointer to a variable local to that function? i.e.: >function foo(x,y : sometype) : somepointertype; >var > z : sometype; >begin > z := whatever you want here;
>end; >This seems to work OK, but I can't see if it is strictly legal.
It doesn't work reliably, because once you exit the function, the memory area used by z will be used by some other routine. What you should do is allocate the result on the heap; that will outlast the function call. Quote: >bar(foo(w,x),foo(y,z));
When you do something like this with the result of foo() allocated on the heap, you have to be careful not to orphan those allocations. Your bar routine should dispose them, or make use of them. If you don't do this, then every call to bar will cause you to lose two z's worth of space on the heap, and your program may eventually run out. A sometimes better alternative to these tricks is just to use a procedure with a var parameter which it modifies, rather than writing foo as a function. Another alternative is to use a compiler that can return structured types, not just pointers to them; Delphi can do this, as can various other Pascal compilers, but not TP/BP. Duncan Murdoch
|
Wed, 18 Jun 1902 08:00:00 GMT |
|
|
R. E. Donai #4 / 4
|
functions returning pointers
Quote:
>Two questions: >1) Is it acceptable practice to define a function which returns a >pointer to a variable local to that function? i.e.: >function foo(x,y : sometype) : somepointertype; >var > z : sometype; >begin > z := whatever you want here;
>end;
When foo ends, z ceases to exist, therefore foo is returning pointer to the big bit bucket in the sky! Quote: >This seems to work OK, but I can't see if it is strictly legal.
If it works it is only because the stack has not yet been exercised enough to destroy z which is dead but doesn't yet know it. Quote: >2) Assuming the above is OK, is there a work-around for the problem that >occurs when you define a second function as: >function bar(p,q : somepointertype) : anothertype; >begin > whatever you want to do here >end; >and call it using returns from foo as arguements?: >bar(foo(w,x),foo(y,z)); >This doesn't work as the first pointer appears to be corrupted when foo is >called the second time. Any obvious solutions? >-- >Mike Fee
>Industrial Research Limited
Well, I was going to suggest that foo's "z" be declared as a constant, then you could return the pointer to it and it would survive after foo ends, But the next. An alternate solution would be to declare "z" as a const pointer to something and set it to nil. When foo is called, if can get a new "z" if it is nil, or dispose "z" if it is not nil and always get a new one. Both methods allow "z" to live only until the next call to foo. There are other variations on this theme, but the best solution is to have foo always get a new "z" and return the pointer to it. Then make it the caller's responsibility to dispose of the object/record when it is no longer needed. ...red Knowledge is one of the few things that you can give away and still keep for yourself.
|
Wed, 18 Jun 1902 08:00:00 GMT |
|
|
|