473,320 Members | 2,133 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

on returning a ptr in a local stack

All
Beginner/Intermediate level question. I understand that returning
ptr to local stack vars is bad.

Is returning foo_p_B from fnB() reliable all the time, so that using
foo_p_A does not break?

Thanks
Josh

fnA()
{
struct foo* foo_p_A;
int a=1, b=2;

foo_p_A = fnB( a, b);

/* Will this work all the time? */
foo_p_A->xxx
}

struct foo*
fnB( int a, int b)
{
struct foo* foo_p_B;

foo_p_B = fnC(a,b);

return foo_p_B;
}

struct foo*
fnC(int c, int d)
{
struct foo* foo_p_C;
....
foo_p_C = (struct foo*) malloc(...);
...
return foo_p_C;
}

Dec 19 '06 #1
6 1766
st*********@gmail.com writes:
Is returning foo_p_B from fnB() reliable all the time, so that using
foo_p_A does not break?
Yes: it is a pointer to an object with allocated lifetime (unless
the call to malloc returns null). A pointer into allocated
storage remains valid until the storage is freed.
--
"It would be a much better example of undefined behavior
if the behavior were undefined."
--Michael Rubenstein
Dec 19 '06 #2
In article <11*********************@t46g2000cwa.googlegroups. com>,
<st*********@gmail.comwrote:
>All
Beginner/Intermediate level question. I understand that returning
ptr to local stack vars is bad.
Yes. The reason for that is that the local variable goes away when the
function returns, so you're left with a pointer that no longer points
at anything.

(Note also that the "stack" you refer to need not look anything like
what you probably think it looks like[1].)

Is returning foo_p_B from fnB() reliable all the time, so that using
foo_p_A does not break?
[Code kept below for reference]

Yes, assuming that it's not NULL (which you don't seem to be checking
for). The pointer that fnB returns originally came from malloc, and
anything you get from malloc will exist until you free it.

The thing to remember here is that a pointer is a /value/ that tells
you where to find an /object/. As long as it's pointing at something
that still exists (that is, the the pointer value refers to an object
that hasn't disappeared), you can pass that value up, down, or sideways
through the call stack with wild abandon, and you can use it to access
the object it refers to anywhere; but when the object it refers to stops
existing (for example, when the function invocation that created a local
variable returns, or when the memory obtained from malloc() is given to
free()), you can't use the pointer value anymore either.

(Note that the more different places you've put any particular pointer
value, the harder it is to make sure that all of those places know when
the object it's pointing at stops existing, so in general it's a good
idea to abandon abandon and pass pointer values around with great care.)
As a side note, your malloc call looks like this:
foo_p_C = (struct foo*) malloc(...);
(and there's a good chance that the "..." part includes "sizeof(struct
foo)" somewhere).

It would be a good idea to get in the habit of writing your mallocs
like this instead:
foo_p_C = malloc(nelems * sizeof *foo_p_C);

The void * that malloc returns will be converted to the appropriate type
by the compiler (if it complains, that means either you haven't told the
compiler what type malloc returns and you should #include <stdlib.h>
or you're using a C++ compiler and you should be using new instead of
malloc), and using "sizeof *pointer_on_left_side_of_assignment" saves
you the trouble of looking up which type it is (and saves you the trouble
of changing all your mallocs if you change the type).
fnA()
{
struct foo* foo_p_A;
int a=1, b=2;

foo_p_A = fnB( a, b);

/* Will this work all the time? */
foo_p_A->xxx
}

struct foo*
fnB( int a, int b)
{
struct foo* foo_p_B;

foo_p_B = fnC(a,b);

return foo_p_B;
}

struct foo*
fnC(int c, int d)
{
struct foo* foo_p_C;
....
foo_p_C = (struct foo*) malloc(...);
...
return foo_p_C;
}

dave

[1] All that's actually required of it is that it can store and manage
function invocation records in a stack-like fashion. Your
implementation probably uses a contiguous block of memory that it
indexes with a register to keep track of where it is, but there have
been real implementations that have done it in heap-allocated blocks,
and there's nothing other than common sense and lack of creativity
that prevents an implementation from putting them in a cave somewhere
in Antarctica.

--
Dave Vandervies dj******@csclub.uwaterloo.ca
I'd abandon abandon if I were you, and jump from record to record with
extreme care. --Richard Heathfield and Bill
The requirements call for abandon, so abandon it has to be. Godfrey in CLC
Dec 19 '06 #3
Rg
You seem to be misunderstanding two different concepts...

Very briefly:

- It's bad, evil, awful to return the *address* of an object locally
declared, unless this object is *static*.

- It's OK to keep an address of a non-local object in a local pointer
and return this address to a callee function.

Amike,
rg
st*********@gmail.com wrote:
All
Beginner/Intermediate level question. I understand that returning
ptr to local stack vars is bad.

Is returning foo_p_B from fnB() reliable all the time, so that using
foo_p_A does not break?

Thanks
Josh

fnA()
{
struct foo* foo_p_A;
int a=1, b=2;

foo_p_A = fnB( a, b);

/* Will this work all the time? */
foo_p_A->xxx
}

struct foo*
fnB( int a, int b)
{
struct foo* foo_p_B;

foo_p_B = fnC(a,b);

return foo_p_B;
}

struct foo*
fnC(int c, int d)
{
struct foo* foo_p_C;
....
foo_p_C = (struct foo*) malloc(...);
...
return foo_p_C;
}
Dec 19 '06 #4
Thank you all for the comments...was really helpful.

Just fyi...the code below malloc does check for null

Thanks
Josh.

On Dec 19, 10:36 am, dj3va...@caffeine.csclub.uwaterloo.ca (Dave
Vandervies) wrote:
In article <1166551672.835525.76...@t46g2000cwa.googlegroups. com>,
Dec 19 '06 #5

<st*********@gmail.comwrote in message
news:11*********************@t46g2000cwa.googlegro ups.com...
All
Beginner/Intermediate level question. I understand that returning
ptr to local stack vars is bad.

Is returning foo_p_B from fnB() reliable all the time, so that using
foo_p_A does not break?

Thanks
Josh

fnA()
{
struct foo* foo_p_A;
int a=1, b=2;

foo_p_A = fnB( a, b);

/* Will this work all the time? */
foo_p_A->xxx
Yes. But you need to free foo_p_A before returning from fnA
or you will have a memory leak.
}

struct foo*
fnB( int a, int b)
{
struct foo* foo_p_B;

foo_p_B = fnC(a,b);
foo_p_B now points to malloc'd memory - not local memory.
No problem returning it to the caller.
>
return foo_p_B;
}

struct foo*
fnC(int c, int d)
{
struct foo* foo_p_C;
....
foo_p_C = (struct foo*) malloc(...);
Do not cast malloc. It will hide the fact that you neglected
to #include <stdlib.h>
...
return foo_p_C;
}
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project


Dec 19 '06 #6
"Rg" <rg*****@gmail.comwrites:
You seem to be misunderstanding two different concepts...
[snip]

Please don't top-post.

Read the following:

http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 19 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Andrew Fleet | last post by:
Hi, I'm looking at returning a reference to an array I create within a subroutine. I could do this... sub foo { my @theArray; <snip>
19
by: JKop | last post by:
When I compile and run the following on my system: #include <iostream> static int hello = 78; int ReturnValue(void) {
3
by: Milan Gornik | last post by:
Hello to all, My question is on right way of returning newly created class from a function (and thus, from class method or operator). As I currently see it, there are two different ways to...
7
by: wonderboy | last post by:
Hey guys, I have a simple question. Suppose we have the following functions:- //-----My code starts here char* f1(char* s) { char* temp="Hi"; return temp;
6
by: Generic Usenet Account | last post by:
Is it okay to return a local datastructure (something of type struct) from a function, as long as it does not have any pointer fields? I think it is a bad idea, but one of my colleagues does not...
19
by: Manish Tomar | last post by:
Hi All, The following code as per my knowledge should not work: int* some() { int b = 10; return &b; }
17
by: I.M. !Knuth | last post by:
Hi. I'm more-or-less a C newbie. I thought I had pointers under control until I started goofing around with this: ...
4
by: rsa_net_newbie | last post by:
Hi there, I have a Managed C++ object (in a DLL) which has a method that is defined like ... Generic::List<String^>^ buildList(String^ inParm) Now, when I compile it, I get "warning C4172:...
17
by: daniel | last post by:
Hello , How safe is it to return a structure from a function. Let's say we have the following situation: typedef struct MyStruct{ int a;
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.