C question and memory

AgentEL

Golden Member
Jun 25, 2001
1,327
0
0
I know this is bad:

int * f1(){
int j;

j=100;

return &j;
}

When f1 returns, the memory taken by j may or may not be reclaimed, which is bad.

But is this bad?

void f2(){
int j;

f3(&j);

return;
}

void f3(int * ptr){
printf("%d\n", *ptr);
}

I would say the contents of j will still be preserved since f2 hasn't yet returned. Can anyone confirm this, please? Thanks!
 

Odoacer

Senior member
Jun 30, 2001
809
0
0
I'm not sure but if you do something like this:

int *foo = f1();

Then free 'foo' accordingly then you should be OK.

This is just a guess though. I'm still a bit vague about memory allocation myself.
 

Nothinman

Elite Member
Sep 14, 2001
30,672
0
0
At first glance that should work fine because when f3 is called j will still be in scope so you can pass it's value or data round.

I'm not sure but if you do something like this:

int *foo = f1();

Then free 'foo' accordingly then you should be OK.

This is just a guess though. I'm still a bit vague about memory allocation myself.

You missed the point. The problem with his first situation is that he returns &j which is the memory address at which j is kept, but after f1() returns j will be out of scope and won't exist so the memory address will be invalid. Worst case the program will crash from a segfault and best case the program will continue but with random data being at &j which will most likely corrupt the results of whatever the rest of the program is doing.
 

Odoacer

Senior member
Jun 30, 2001
809
0
0
Originally posted by: Nothinman
At first glance that should work fine because when f3 is called j will still be in scope so you can pass it's value or data round.

I'm not sure but if you do something like this:

int *foo = f1();

Then free 'foo' accordingly then you should be OK.

This is just a guess though. I'm still a bit vague about memory allocation myself.

You missed the point. The problem with his first situation is that he returns &j which is the memory address at which j is kept, but after f1() returns j will be out of scope and won't exist so the memory address will be invalid. Worst case the program will crash from a segfault and best case the program will continue but with random data being at &j which will most likely corrupt the results of whatever the rest of the program is doing.

I thought the value would be kept after the function returns, but I see what you're saying about &j going out of scope. How about passing &j as a parameter? Would that work?
 

Nothinman

Elite Member
Sep 14, 2001
30,672
0
0
I thought the value would be kept after the function returns, but I see what you're saying about &j going out of scope. How about passing &j as a parameter? Would that work?

That would require allocationg j outside of the f1 call and passing it's address into f1 which changes the API of f1, but yes it would still be in scope after f1 returns control back to the calling function.
 

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0

Your first example is returning the address of something that is on the stack and goes out of scope immediately after you return, leading to the results that Nothinman described. The second example looks fine to me, although obviously for an int, a pointer is silly (I'm assuming it is a simplification of your real code).
 

kylef

Golden Member
Jan 25, 2000
1,430
0
0
As a general rule of thumb, passing the address of stack-allocated ("local") variables as a parameter to a function is OK as long as the function doesn't store the address for later use elsewhere (i.e., after the function returns). That can create a construct known as a "dangling reference", which is what Nothinman was talking about. The memory address would point to an invalid memory location:

int * g_pTheResult; // global pointer to the result of the calculation

int main() {
Calculate();
if ( NULL != g_pTheResult ) {
printf("The result is %d", *pTheResult); // may crash here!
}
return 0;
}

void Calculate() {
int i;
i = 1 + 2 + 3;
g_pTheResult = &i; // error! g_pTheResult is dangling as soon as Calculate() exits
}

The scary part is that the above code might actually RUN and produce the correct output. It's due to the fact that the discarded stack frame from Calculate() is still "sitting around" and simply hasn't been overwritten. So when printf() reads from the address located on this defunct stack frame, the old result (6) will still be there. And while the address is technically invalid, the OS won't be able to detect the invalid memory access because it can only detect invalid Page accesses. Because x86 architectures use 4kb pages and the above functions have stack frames that are only a few bytes long, there is a high probability that both stack frames are on the same (valid) page and the OS would not catch the violation.

Note that the problem with the code above has nothing to do with "reclaiming memory". Reclaiming memory is only an issue when you're dealing with heap-allocated ("dynamic") variables. The compiler ensures all local variables are "reclaimed" appropriately. The programmer gets this for free.
 

Titan

Golden Member
Oct 15, 1999
1,819
0
0
Originally posted by: BingBongWongFooey
Your first example is returning the address of something that is on the stack and goes out of scope immediately after you return, leading to the results that Nothinman described. The second example looks fine to me, although obviously for an int, a pointer is silly (I'm assuming it is a simplification of your real code).

Ditto.

Automatic variables are deallocated when the closing } is reached, and never before. Many many system calls on all kinds of platforms take pointers or are call-by-reference. If the data local to your function is passed to another function (even through a pointer) it better still exist!
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |