Hi,
do you think that this is a correct use of malloc function?
No, for several reasons, detailed below.
void foo(void)
{
....
prt++;
I assume that was intended to be ptr++.
Conforming implementations of C are not required to accept main() being
declared as returning void. Many books have been written as if this were
a good idea; if you have such a book, and are free to choose to use a
different book, do so - there's no telling how many other bad habits
that book may be teaching you. Many compilers have been designed to
accept it, but you should not use it. You should always declare main()
as returning int.
{
int *ptr=malloc(5*sizeof(int));
It's generally better to use sizeof *ptr. That way, if at some point in
the future you decide to change the type that ptr points at, you only
need to change the type in one location.
If the declaration of ptr is in a different location than the place
where you call malloc() (an issue that will become important down below)
then it's even more important to use this method. Given the following
statement:
car_list = malloc(num_cars * sizeof *car_list);
The fact that the correct size is being referred to can determined just
by looking at that one statement. If you use sizeof(type), you must also
look at the declaration of car_list to make sure that it's the size of
the right type.
You should always check whether malloc() returns a null pointer. If it
does, it means that malloc() failed, and the behavior of a program that
dereferences a null pointer is undefined.
....
foo();
free(ptr);
}
Can i use ptr in foo() function without passing it?
Thanks
No. C variables can only be accessed by name within their scope. The
scope of ptr starts immediately after the "ptr" in it's declaration in
main(), and extends all the way to the '}' that ends the body of main()
- but it does not include functions that are called from within main().
The other issues I'm raising in this message are just a matter of "best
practices"- you'll often get away with writing code this sloppy - but
that's not the case here. You simply cannot use ptr that way.
Passing the pointer value as an argument to foo() is the single best way
to deal with this issue. However, on rare occasions that might not be
possible, such as when writing callback functions with a fixed
interface, such as the comparison functions used by qsort() or
bsearch(). If that's the case, one alternative is to use a file scope
variable, which can be used anywhere in the same file below the the
point where it's declared:
int *ptr;
void foo(void)
{
...
ptr++;
}
int main()
{
ptr = malloc(5*sizeof *ptr);
if(ptr)
{
foo();
free(ptr);
ptr = NULL;
}
return 0;
}
When you free() a piece allocated memory, all pointers that used to
refer to any part of that memory have indeterminate values. That means
that you cannot safely use them for ANY purpose, not even checking them
for equality with another pointer value. If there's any chance that a
pointer object might be used again after you free the memory it refers
to, you should re-set it to a null value, which can at least be safely
checked for equality. The code which uses that value can check whether
it's null, and use that fact to avoid doing anything else with it. In
this particular case, it's easy to see that ptr will never be used again
- but I make it a habit to always null such pointers unless the pointer
object's lifetime is guaranteed to end before the very next statement
gets executed; ptr's lifetime continues after the return statement is
executed (though not for very long after that point).
Explicitly returning 0 from main() is not strictly necessary; special
rules were added to C99 to allow it. However, those special rules were a
concession to a popular piece of bad programming - it's a bad idea to
take advantage of those rules. You should develop a habit of always
making sure that any function declared as returning a value does in fact
return a value (unless you're certain that the value will not be used -
but the value returned by the initial call to main() in a program is
always used).