Pointer in functions

R

raghu

look at the code below
#include <stdio.h>
int * get_number(int i);

main()
{
int *krrk[5];
int i = 0;
printf(" testing the address of a variable in the function\n i
address in main %u\n", &i);
krrk = get_number(i);
printf("for = i %d address %u and its contents %d\n", i, krrk,
*krrk);
for(i = 1; i < 5; i++)
{

krrk = get_number(i);
printf("for i = %d address %u and its contents %d\n", i, krrk,
*krrk);
printf("for i - 1 = %d address %u and its contents %d\n", i - 1,
krrk[i - 1], *krrk[i - 1]);
}
for( i = 0 ; i < 5; i++)
{
printf(" for i = %d address of %d is %u\n", i, *krrk, krrk);
}
}
int * get_number(int i)
{
return &i;
}
output of this file (I got) is as follows
testing the address of a variable inthe function
i address in main 2280636
for i = 0 address 2280576 and its contents 0
for i = 1 address 2280576 and its contents 1
for i -1 = 0 addrss 2280576 and its contents 4202616
for i = 2 address 2280576 and its contents 2
for i -1 = 1 addrss 2280576 and its contents 4202616
for i = 3 address 2280576 and its contents 3
for i -1 = 2 addrss 2280576 and its contents 4202616
for i = 4 address 2280576 and its contents 4
for i -1 = 3 addrss 2280576 and its contents 4202616

for i = 0 address of 4202660 is 2280576
for i = 1 address of 4202708 is 2280576
for i = 2 address of 4202708 is 2280576
for i = 3 address of 4202708 is 2280576
for i = 4 address of 4202708 is 2280576


my doubt is here I am returning a local variable of a function
and so Its get corrupted for the next call(if same address is assigned
to that local variable) but here I am getting a garbage value(4202616)
when I pointing to same address again. why?

In the second for loop I am getting different values than before
why?

awaiting for ur reply
- Raghu
 
E

Eric Sosman

raghu wrote On 11/14/07 15:04,:
look at the code below
[...]
int * get_number(int i)
{
return &i;
}
output of this file (I got) is as follows
[...]

I don't think the code you posted produced the
output you showed. I think you re-typed one or the
other, possibly both, and introduced discrepancies
along the way. Please don't do that any more; post
*exactly* the code you used and the output you got.
my doubt is here I am returning a local variable of a function
and so Its get corrupted for the next call(if same address is assigned
to that local variable) but here I am getting a garbage value(4202616)
when I pointing to same address again. why?

In the second for loop I am getting different values than before
why?

The answer to both questions is "The program invokes
undefined behavior, so anything at all can happen. No
outcome, however it may startle you, should be in the
least bit surprising."

In this case, it seems likely that the value returned
by get_number() points to a location on a stack, a location
that has been "popped away" by the time get_number()
returns and is no longer in use when the caller regains
control. Since the pointed-to stack location is unused,
other parts of the system use it for their own purposes
and leave various kinds of garbage in it as they go
about their business. Your main() function tries to make
use of the garbage; that's Not Recommended.

You have written your name in the wet sand, and then
let the tide wash in and out several times. Someone now
asks your name, and you tell him to go down to the beach
and read it. He does so, returns, and greets you with
a cheery "Hello, Seaweed!" Why should you be surprised?
 
P

pete

raghu said:
look at the code below
#include <stdio.h>
int * get_number(int i);

main()
{
int *krrk[5];
int i = 0;
printf(" testing the address of a variable in the function\n i
address in main %u\n", &i);
krrk = get_number(i);
printf("for = i %d address %u and its contents %d\n", i, krrk,
*krrk);
for(i = 1; i < 5; i++)
{

krrk = get_number(i);
printf("for i = %d address %u and its contents %d\n", i, krrk,
*krrk);
printf("for i - 1 = %d address %u and its contents %d\n", i - 1,
krrk[i - 1], *krrk[i - 1]);
}
for( i = 0 ; i < 5; i++)
{
printf(" for i = %d address of %d is %u\n", i, *krrk, krrk);
}
}
int * get_number(int i)
{
return &i;
}
output of this file (I got) is as follows
testing the address of a variable inthe function
i address in main 2280636
for i = 0 address 2280576 and its contents 0
for i = 1 address 2280576 and its contents 1
for i -1 = 0 addrss 2280576 and its contents 4202616
for i = 2 address 2280576 and its contents 2
for i -1 = 1 addrss 2280576 and its contents 4202616
for i = 3 address 2280576 and its contents 3
for i -1 = 2 addrss 2280576 and its contents 4202616
for i = 4 address 2280576 and its contents 4
for i -1 = 3 addrss 2280576 and its contents 4202616

for i = 0 address of 4202660 is 2280576
for i = 1 address of 4202708 is 2280576
for i = 2 address of 4202708 is 2280576
for i = 3 address of 4202708 is 2280576
for i = 4 address of 4202708 is 2280576

my doubt is here I am returning a local variable of a function
and so Its get corrupted for the next call(if same address is assigned
to that local variable) but here I am getting a garbage value(4202616)
when I pointing to same address again. why?

In the second for loop I am getting different values than before
why?


The whole program makes no sense.
You're trying to display the addresses and values of rvalues.
rvalues don't have addresses.
 
R

raghu

raghu wrote On 11/14/07 15:04,:
look at the code below
[...]
int * get_number(int i)
{
return &i;
}
output of this file (I got) is as follows
[...]

I don't think the code you posted produced the
output you showed. I think you re-typed one or the
other, possibly both, and introduced discrepancies
along the way. Please don't do that any more; post
*exactly* the code you used and the output you got.
The code above is the same one which I compiled and exectued. I just
copied the code only after executing the code and output is the same
one I am got. I am using cygwin in windows machine.
The answer to both questions is "The program invokes
undefined behavior, so anything at all can happen. No
outcome, however it may startle you, should be in the
least bit surprising."

In this case, it seems likely that the value returned
by get_number() points to a location on a stack, a location
that has been "popped away" by the time get_number()
returns and is no longer in use when the caller regains
control. Since the pointed-to stack location is unused,
other parts of the system use it for their own purposes
and leave various kinds of garbage in it as they go
about their business. Your main() function tries to make
use of the garbage; that's Not Recommended.
I got it. Is it okay to pass structure instance.
look at the following code and the authors claims that its working
mac_ipc_send_ipc_msg ( char *mq_name,
int mq_id,
int options,
IPC_MSG_TYPE msgtype,
int msglen,
char *data,
void (*cb)(void *))
{
ipc_msg_hdr_t msg ;

msg.type = msgtype;
msg.len = msglen ;
msg.data = data;
msg.free_cb = cb;

return vos_mq_send(mq_name,
mq_id,
(char *)&msg,
sizeof(ipc_msg_hdr_t),
(int)MSG_PRI_NORMAL);
}
In the above code vos_mq_send is similar msgQCreate() function.
then what will be the behaviour of 'msg' variable. Will it works?
The testers also saying that it works. I didn't understand why?
Any comments on this.
 
K

Keith Thompson

raghu said:
look at the code below

I'll just make a few comments.
#include <stdio.h>
int * get_number(int i);

main()

This should be "int main(void)".
{
int *krrk[5];
int i = 0;
printf(" testing the address of a variable in the function\n i
address in main %u\n", &i);

"%u" is the wrong format to print an address. To print an address,
use "%p". Since "%p" specifically requires a void*, and since in
this particular case, the compiler doesn't know that it needs to do
an implicit conversion, you need to convert explicitly to void*.

Also, "%p" typically uses a format that makes sense for the platform
(typically hexadecimal).

So:

printf("Address of i is %p\n", (void*)&i);

[...]
int * get_number(int i)
{
return &i;
}

This function doesn't do anything useful. Function arguments are
passed by value in C. In other words, an argument (an expression
between parentheses in a function call) is evaluated, and its value
is *copied* and assigned to the parameter (your "int i", which is a
local variable within the function).

Inside get_number, you take the address of this local variable,
which has nothing to do with the argument you passed to the function
(except that the argument value was copied to it). Once you leave
the function, the local variable (the parameter) no longer exists,
and its address is completely meaningless.
 
E

Eric Sosman

raghu wrote On 11/14/07 17:41,:
raghu wrote On 11/14/07 15:04,:

look at the code below
[...]
int * get_number(int i)
{
return &i;
}
output of this file (I got) is as follows
[...]

I don't think the code you posted produced the
output you showed. I think you re-typed one or the
other, possibly both, and introduced discrepancies
along the way. Please don't do that any more; post
*exactly* the code you used and the output you got.

The code above is the same one which I compiled and exectued. I just
copied the code only after executing the code and output is the same
one I am got. I am using cygwin in windows machine.

I still don't believe you. Here's the first output
call in your program source:
printf(" testing the address of a variable in the function\n i
address in main %u\n", &i);

.... and here is the first line of output:
testing the address of a variable inthe function
i address in main 2280636

What happened to the space between "in" and "the"? What
happened to the space at the start of the second output line?

The second output call is:
printf("for = i %d address %u and its contents %d\n", i, krrk,
*krrk);


.... and the output it supposedly produced is:
for i = 0 address 2280576 and its contents 0

How did the "i" and the "=" get transposed? True, this one
might not be your fault: The program invokes undefined behavior
before attempting this printf() call, and it's conceivable that
the symptom of the undefined behavior is to swap i's and ='s
in all subsequent output. Doesn't seem likely, though.
I got it. Is it okay to pass structure instance.

You still don't quite get it, or don't seem to. The error
in the first program isn't that the returned value is a pointer,
but that it points to something -- a function parameter -- that
ceased to exist when the function returned. The function has
returned the "telephone number" of a "telephone" that was
destroyed in the process of returning.
look at the following code and the authors claims that its working
mac_ipc_send_ipc_msg ( char *mq_name,
int mq_id,
int options,
IPC_MSG_TYPE msgtype,
int msglen,
char *data,
void (*cb)(void *))
{
ipc_msg_hdr_t msg ;

msg.type = msgtype;
msg.len = msglen ;
msg.data = data;
msg.free_cb = cb;

return vos_mq_send(mq_name,
mq_id,
(char *)&msg,
sizeof(ipc_msg_hdr_t),
(int)MSG_PRI_NORMAL);
}
In the above code vos_mq_send is similar msgQCreate() function.
then what will be the behaviour of 'msg' variable. Will it works?
The testers also saying that it works. I didn't understand why?
Any comments on this.

The msg variable is created when mac_ipc_send_ipc_msg()
starts, and exists until it returns. Before it returns,
it calls vos_mq_send(), which runs to completion and returns
a value. After this happens, mac_ipc_send_ipc_msg() itself
returns, passing the same value to its caller.

While vos_mq_send() is running, mac_ipc_send_ipc_msg()
has not yet returned. So msg has not yet been destroyed,
and vos_mq_send() can safely use the pointer to it. The
destruction of msg happens when mac_ipc_send_ipc_msg()
returns, not while it is merely "suspended" to allow a
called function to run.
 
K

Kenneth Brody

raghu said:
look at the code below [...]
int * get_number(int i)
{
return &i;
} [...]
my doubt is here I am returning a local variable of a function
and so Its get corrupted for the next call(if same address is assigned
to that local variable) but here I am getting a garbage value(4202616)
when I pointing to same address again. why?

You're not returning a local variable. You're returning the
address of a local variable. That pointer becomes invalid
as soon as the function returns. Derefencing that pointer
invokes undefined behavior. (And, while simply dereferencing
it is unlikely to cause problems on most systems, using the
value stored there will cause problems.)
In the second for loop I am getting different values than before
why?

Because UB can cause anything to happen.

In your case, the address is likely to point to the last paramaeter
passed to the most recent function call, but even that guess is
just a guess.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,161
Latest member
GertrudeMa
Top