Doubt about pass pointer to int.

C

CViniciusM

Hello,

The output of the code below is:
number = 10
number = 0 (or other number except 15)

Why the output of the second 'number' is not 15? Why the 'number' address is
not changed?

Thanks in advance, Vinicius.


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

void change_int(int *num);

int main(void)
{
int *number;

number = (int *) malloc(sizeof(int));
*number = 10;
printf("number = %d\n", *number);
change_int(number);
printf("number = %d\n", *number);

free(number);
system("PAUSE");
return 0;
}

void change_int(int *num)
{
int *temp;

temp = num;
num = (int *) malloc(sizeof(int));
*num = 15;
free(temp);
}
 
F

fix

CViniciusM said:
Hello,

The output of the code below is:
number = 10
number = 0 (or other number except 15)

Why the output of the second 'number' is not 15? Why the 'number' address is
not changed?

Thanks in advance, Vinicius.


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

void change_int(int *num);

int main(void)
{
int *number;

number = (int *) malloc(sizeof(int));
*number = 10;
printf("number = %d\n", *number);
change_int(number);
printf("number = %d\n", *number);

free(number);
system("PAUSE");
return 0;
}

void change_int(int *num)
{
int *temp;

temp = num;
num = (int *) malloc(sizeof(int));
*num = 15;
free(temp);

Just a newbie to C, but I guess this line is the problem.
temp and num is pointing to the same allocated memory,
you free temp means you free num,
and then num is now pointing to some unknown stuffs.
 
A

Artie Gold

CViniciusM said:
Hello,

The output of the code below is:
number = 10
number = 0 (or other number except 15)

Why the output of the second 'number' is not 15? Why the 'number' address is
not changed?

Well, since you've invoked undefined behavior in your code, *anything*
could have happened. See below.
#include <stdio.h>
#include <stdlib.h>

void change_int(int *num);

int main(void)
{
int *number;

number = (int *) malloc(sizeof(int));
Better:
number = malloc(sizeof *number);
if (number == NULL) {
puts("Allocation of `number' failed.");
exit(EXIT_FAILURE);
}
*number = 10;
printf("number = %d\n", *number);
change_int(number);
Remember, the value of `number', a pointer to int, is passed to the
function change_int().

First see the comments in the function change_int() below, then come
back here.
printf("number = %d\n", *number);

OK, you're back. ;-)

Whoops. `number' no longer points to valid memory, as it has been freed
in change_int(). You have now invoked undefined behavior.
free(number);
Double whoops. You've now freed the same memory twice. UB again!
system("PAUSE");
return 0;
}

void change_int(int *num)
{
int *temp;

temp = num;
`temp' now points to the same int as `number' in main().
num = (int *) malloc(sizeof(int));
Better:
num = malloc( sizeof *num);
if (num == NULL) {
puts("allocation of `num' in `change_int' failed");
exit(EXIT_FAILURE);
}
*num = 15;
`num' now points to memory containing the int 15.
free(temp);
The memory originally allocated to `number' in main() is freed.
*And*, since `num' now goes out of scope, the memory allocated to it can
no longer be referenced. MEMORY LEAK!

Remember, in C, parameters are /passed by value/. If you want to side
effect a parameter, you need to pass a pointer to it.

HTH,
--ag
 
L

Leor Zolman

Hello,

The output of the code below is:
number = 10
number = 0 (or other number except 15)

Why the output of the second 'number' is not 15? Why the 'number' address is
not changed?

Thanks in advance, Vinicius.

When dealing with dynamic memory allocation, keep in mind that each call to
malloc() should be balanced by exactly one call to free(), passing free()
the value obtained from the malloc() call. With that in mind...
#include <stdio.h>
#include <stdlib.h>

void change_int(int *num);

int main(void)
{
int *number;

number = (int *) malloc(sizeof(int));
*number = 10;
printf("number = %d\n", *number);
change_int(number);
printf("number = %d\n", *number);
free(number);

This should either be the first time the value in number is being passed to
free() (it isn't), or the first time you've made an attempt to free
whatever dynamically-allocated pointer is currently in number (that isn't
the case, either.)
system("PAUSE");
return 0;
}

void change_int(int *num)
{
int *temp;

temp = num;

At this point both temp /and/ num point to the int you're presumably trying
to change...
num = (int *) malloc(sizeof(int));

But now you have overwritten the address of that int in num with the
address of a new, dynamically allocated piece of memory. BTW, don't bother
to cast, it isn't necesesary in C:

num = malloc(sizeof(int));
*num = 15;

You are now setting the value of the dynamically allocated int you just
obtained in the previous statement.
free(temp);

You've just freed the dynamic memory that you allocated in main() (pointed
to by "number" there), and on top of that, the memory pointed to by "num"
has just been leaked (you've lost that pointer, never to be regained)

So, think about all that and give it another shot...
Good luck,
-leor


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
R

Richard Heathfield

CViniciusM said:
Hello,

The output of the code below is:
number = 10
number = 0 (or other number except 15)

Why the output of the second 'number' is not 15? Why the 'number' address
is not changed?

Thanks in advance, Vinicius.


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

void change_int(int *num);

int main(void)
{
int *number;

number = (int *) malloc(sizeof(int));

The cast is unnecessary.

Check that malloc succeeded before relying on its return value for storage
purposes. (If it failed, it will return NULL.)
*number = 10;
printf("number = %d\n", *number);
change_int(number);
printf("number = %d\n", *number);

free(number);
system("PAUSE");

On my system, this call issues the message:

PAUSE: command not found


return 0;
}

void change_int(int *num)
{
int *temp;

temp = num;
num = (int *) malloc(sizeof(int));
*num = 15;
free(temp);
}

C is a pass-by-value language. Your change_int function does this:

1) save a pointer to your sizeof(int) bytes, using temp.
2) allocate some fresh memory, using a local variable (yes, num is local to
change_int -- it's just a *copy* of the original pointer from main(), and
will be destroyed on exit).
3) assign 15 to the storage thus allocated (assuming the allocation request
didn't fail).
4) give up the memory you originally allocated in main().
5) return, in the course of which all local objects are destroyed, including
your one-and-only pointer to the new block of memory.

When you get back to main(), you printf("%d\n", *number) - BUT the memory
that this pointer pointed to was freed in change_int(). So the access is
invalid.

Your change_int() function can be rewritten very simply:

void change_int(int *num)
{
*num = 15;
}

Try it and see. :)
 
R

Richard Heathfield

fix said:
Just a newbie to C, but I guess this line is the problem.
temp and num is pointing to the same allocated memory,
you free temp means you free num,

No, because num has acquired a new value by that time. You are, however,
right in thinking that this function has BIG problems. :)
 

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,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top