Why would malloc() modify the behavior of this output?

G

grocery_stocker

If go like the following:

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;
}

main(void){
char *j;

j = test_me(1);

printf("The value of j is : %x", *j);

}

I get:
The value of j is : 1


However, when I add malloc()

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;
}

main(void){
char *p;
char *j;

p = malloc(10);
j = test_me(1);

printf("The value of p is : %x", *p);
printf("The value of j is : %x", *j);

free(p);
}

I get the following:
The value of p is : 0
The value of j is: ffffffc4

Why does p become zero?
 
A

Artie Gold

grocery_stocker said:
If go like the following:

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;

Please notice that you're not returning anything from this function,
though its signature indicates a pointer to void will be returned.
Undefined behavior. All bets are off.
}

main(void){
char *j;

j = test_me(1);

Again, since test_me() fails to return anything, the value of `j' is
indeterminate.
printf("The value of j is : %x", *j);

}

I get:
The value of j is : 1


However, when I add malloc()

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;
}

main(void){
char *p;
char *j;

p = malloc(10);
j = test_me(1);

printf("The value of p is : %x", *p);
printf("The value of j is : %x", *j);

free(p);
}

I get the following:
The value of p is : 0
The value of j is: ffffffc4

Why does p become zero?
Undefined behavior means the results could be *anything* -- even nasal
demons might ensue.

HTH,
--ag
 
A

August Karlstrom

grocery_stocker said:
If go like the following:

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;
}

main(void){
char *j;

j = test_me(1);

printf("The value of j is : %x", *j);

}

I get:
The value of j is : 1


However, when I add malloc()

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;
}

main(void){
char *p;
char *j;

p = malloc(10);
j = test_me(1);

printf("The value of p is : %x", *p);
printf("The value of j is : %x", *j);

free(p);
}

I get the following:
The value of p is : 0
The value of j is: ffffffc4

Why does p become zero?
My guess is that after test_me has been called the stack is corrupt,
since test_me returns an unspecified value, so p is probably modified by
printf.
 
G

grocery_stocker

So in other words, when in the function test_me(), I should have used
'static'?
 
P

Peter Shaggy Haywood

Groovy hepcat grocery_stocker was jivin' on 10 May 2005 20:10:24 -0700
in comp.lang.c.
Why would malloc() modify the behavior of this output?'s a cool scene!
Dig it!
If go like the following:

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;
}

You should get a diagnostic here. You're not returning anything from
this function. This is no doubt the cause of your problem.
main(void){

int main(void)
{

.... to satisfy C99.
char *j;

j = test_me(1);

j now contains an indeterminate value, because you have failed to
return a value from test_me().
printf("The value of j is : %x", *j);

Since j is indeterminate, dereferencing it here causes undefined
behaviour.

return 0;

.... to satisfy C90.
}

I get:
The value of j is : 1

It could be anything. For that matter, you needn't get any output at
all. The program could crash. Or it could cause a shift in the
space-time continuum which traps you in the 13th dimention. Undefined
behaviour means that ANYTHING the program does is "right".
However, when I add malloc()

#include <stdlib.h>

void *test_me(int a) {
int *m;
m = &a;
}

main(void){

int main(void)
{
char *p;
char *j;

p = malloc(10);

Check! Always check the return value of functions like malloc(). You
must not try to dereference the pointer if malloc() fails.
j = test_me(1);

printf("The value of p is : %x", *p);

*p is uninitialised. Its value is indeterminate. p points to
dynamically allocated memory IF the malloc() call succeeded. but the
memory it points to has not been given a value.
printf("The value of j is : %x", *j);

And once again the value of j is indeterminate, and you are causing
undefined behaviour by dereferencing it.

return 0;
}

I get the following:
The value of p is : 0
The value of j is: ffffffc4

Why does p become zero?

p does not become 0. *p, however, is indeterminate. It could be 0,
but it could be anything else. It just happens to be 0 in this
instance.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
A

Artie Gold

grocery_stocker said:
So in other words, when in the function test_me(), I should have used
'static'?
First of all, it is imperative in Usenet discussions to maintain enough
context to know what you're talking about.

And the answer is: The function test_me() needs to return something. It
doesn't.

HTH,
--ag
 
G

Grumble

Peter said:
It could be anything. For that matter, you needn't get any output at
all. The program could crash. Or it could cause a shift in the
space-time continuum which traps you in the 13th dimention. Undefined
behaviour means that ANYTHING the program does is "right".

Mankind should try to harness the power of UB.

It seems to have even more potential than nuclear fusion.
 
R

Richard Bos

Grumble said:
Mankind should try to harness the power of UB.

It seems to have even more potential than nuclear fusion.

It does, but unfortunately this includes the power not to be harnessed.
It is a bit like Mephistophilis in this way - people who try to harness
the power of uninitialised objects tend to find themselves facing
thunder and lightning at midnight, twenty-four years being expired.

Richard
 
K

Keith Thompson

grocery_stocker said:
printf("The value of j is : %x", *j); [...]
printf("The value of p is : %x", *p);
printf("The value of j is : %x", *j);

Among numerous other errors, you're not printing the values of j and
p. You're printing the values of *j and *p.
 
O

Old Wolf

Peter said:
Groovy hepcat grocery_stocker was jivin':

You should get a diagnostic here. You're not returning
anything from this function. This is no doubt the cause
of your problem.

No diagnostic is required for this situation.
int main(void)
{


j now contains an indeterminate value, because you have
failed to return a value from test_me().

Actually the behaviour became undefined at the point of
test_me() returning. So 'j' could contain any value
(indeterminate or not), or nasal demons, or cease to exist, etc.
Since j is indeterminate, dereferencing it here
causes undefined behaviour.

If j were indeterminate, merely mentioning it would cause
undefined behaviour.
 
A

Al Bowers

grocery_stocker said:
So in other words, when in the function test_me(), I should have used
'static'?

That could help matters because I assume this use of the
static keyword is to deal with the function test_me reurning the
address of a int that doesn't exist once the function returns.

But there are numerous other errors. So many that I probably
will miss some in my comments.

The code fails to include header stdio.h.

Function main returns a int.

Tbe function test_me code does not return a value even though
the prototype calls for a return of void *.

You are attempting to convert a int * to void * to char *.
This does not guarantee that the original pointer(to int *)
will compare equal to the result(char *).
If you converted it back again to int * (int * -> void * -< int *),
the the standard says the result shall compare equal to the
original pointer.

If you rid all this UB then you will see that function
malloc will have no affect on the test.

#include <stdlib.h>
#include <stdio.h>

void *test_me(int a)
{
static int m;
m = a;
return &m;
}

int main(void)
{
int *j, *i;

j = test_me(1);
printf("Test on function test-me before malloc\n"
"The value of j is : %i\n"
"The address of is %x\n\n", *j, (void *)j);
i = malloc(10 * sizeof *i);
printf( "Test on function test_me after malloc\n"
"The value of j is : %d\n"
"The address of is %x\n\n", *j, (void *)j);
free(i);
return 0;
}
 
A

Al Bowers

grocery_stocker said:
So in other words, when in the function test_me(), I should have used
'static'?

That could help matters because I assume this use of the
static keyword is to deal with the function test_me reurning the
address of a int that doesn't exist once the function returns.

But there are numerous other errors. So many that I probably
will miss some in my comments.

The code fails to include header stdio.h.

Function main returns a int.

Tbe function test_me code does not return a value even though
the prototype calls for a return of void *.

You are attempting to convert a int * to void * to char *.
This does not guarantee that the original pointer(to int *)
will compare equal to the result(char *).
If you converted it back again to int * (int * -> void * -< int *),
the the standard says the result shall compare equal to the
original pointer.

If you rid all this UB then you will see that function
malloc will have no affect on the test.

#include <stdlib.h>
#include <stdio.h>

void *test_me(int a)
{
static int m;
m = a;
return &m;
}

int main(void)
{
int *j, *i;

j = test_me(1);
printf("Test on function test-me before malloc\n"
"The value of j is : %d\n"
"The address of is %p\n\n", *j, (void *)j);
i = malloc(10 * sizeof *i);
printf( "Test on function test_me after malloc\n"
"The value of j is : %d\n"
"The address of is %p\n\n", *j, (void *)j);
free(i);
return 0;
}
 
P

pete

Lawrence said:
On Wed, 11 May 2005 12:16:11 -0400, Al Bowers wrote:

...


In order to compare values they have to be of the same type. Once you
ensure that the situation changes.

One of the main probmes with the original code
is the incorrect way that
it attempts to convert the values of pointers (presuming that was
intended). Your version fixes that.


In this case there's int * -> void * -> char * vs. int * -> char *.
Given that void * has the same representation as pointers
to character types it
is difficult to see how these conversion sequences
could produce unequal results from a valid initial value.

There's also that
a pointer to an object, converted to (char *),
becomes a pointer to the lowest addressable byte of the object.
So, even if a (void *) pointer
didn't have any special relation to (char *),
converting a (void *) to (char *),
should yield the address of the lowest addressable byte
of whatever object the (void *) pointer has the address of.

For
int object;
(char *)&object is the address of the lowest addressable byte of object.
(char *)(void *)&object, should be the address of the same byte.

I don't think pointer representation is an issue here.
 
L

Lawrence Kirby

On Wed, 11 May 2005 12:16:11 -0400, Al Bowers wrote:

....
You are attempting to convert a int * to void * to char *.
This does not guarantee that the original pointer(to int *)
will compare equal to the result(char *).

In order to compare values they have to be of the same type. Once you
ensure that the situation changes.

One of the main probmes with the original code is the incorrect way that
it attempts to convert the values of pointers (presuming that was
intended). Your version fixes that.
If you converted it back again to int * (int * -> void * -< int *),
the the standard says the result shall compare equal to the
original pointer.

In this case there's int * -> void * -> char * vs. int * -> char *. Given
that void * has the same representation as pointers to character types it
is difficult to see how these conversion sequences could produce unequal
results from a valid initial value.

Lawrence
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top