George said:
Hello to everybody !!!
Why am i getting always:
size=4 (i understand this)
length=3 (?????)
when i'm executing the following programm?
Should'nt i get always the number of bytes
allocated by "malloc" ??? (in this example 16)
Why is this happening?
Here's a few more details about things that were glossed over in some of
the replies.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
int main(void)
"Implicit int" no longer exists in C. Under the latest standard you must
specify the return type for all functions. In the case of main(), the
return type must be 'int' (contrary to popular belief, 'void' has never
been an acceptable return type for main() in any version of C).
As for the voided parameter list, you should never use empty parameter
lists in C unless you really know what you are doing. In C (unlike C++)
an empty parameter list is very different from a void parameter list,
and empty parameter lists can be very dangerous.
{
char* name;
name=(char*)malloc(16);
It's generally recommended to NOT cast the return from malloc(). At
least one very notable book on C incorrectly states that the cast is
required, but it is not.
The main reasons to not cast are: 1) It can suppress a useful
diagnostic, thus hiding an error in the code (the error in question is a
failure to provide a correct declaration for malloc() - the result of
forgetting to #include <stdlib.h>). 2) The cast is an extra maintenance
concern. If the type of 'name' were to change (say, to unsigned char, or
wchar_t), you'd need to locate and fix every cast expression involving
'name'.
The comp.lang.c-approved method of calling malloc() looks like this:
name = malloc(16 * sizeof(*name) );
(Alternatively, remove the parens on the sizeof operator - they aren't
necessary in this case.)
This form automatically adjusts to changes in the type of 'name', and is
generally more difficult to get wrong than other forms.
if (!name)
{
printf("Mem Alloc Error.");
No one else mentioned this (that I saw), but a portable program needs to
terminate its output with a newline:
printf("Mem Alloc Error.\n");
It's not uncommon for the last line of output to mysteriously disappear,
or to appear with the system prompt tagged onto the end if it is not
correctly terminated.
Also, error output should usually go to the standard error stream:
fprintf(stderr, "Mem Alloc Error.\n");
exit (0);
}
printf("size=%d \n",sizeof(name));
printf("length=%d",strlen(name));
Both of these printfs are wrong. As before, you should end your lines
with a newline character, but more importantly you have used the wrong
format specifiers. This can be a very serious problem, and most
compilers won't warn you about it.
Both sizeof and strlen give a result of type size_t. size_t is an
unsigned type. The %d format specifier is for (signed) int ONLY. It's
possible that size_t could be an alias for unsigned int, but not signed
int. Therefore, %d can never be the correct format specifier for a size_t.
Keep in mind that printf is stupid. It cannot determine the actual types
of the objects you pass it. It relies completely on you telling it the
correct type. If you lie to it about the type, all bets are off. Stack
corruption leading to a program crash or worse is very likely. Even if
it "seems to work", bad things may be happening that aren't easily
observed - mysterious, very difficult to find bugs can pop up. The
behavior can appear random, and may be completely different on a
different system, or when using a different compiler.
In other words, it's very important to get your format strings right.
Always double-check them.
In this case, there probably isn't a format string you can use for
size_t. C99 introduced %zu for this purpose, but you probably aren't
using a C99 compiler. The safest way to print a size_t is to cast it to
a known type first:
printf("length=%lu\n", (unsigned long)strlen(name));
This is guaranteed safe in C versions prior to C99, since size_t can be
no wider than unsigned long. As of C99, size_t can be wider (it can even
be wider than the new 'long long' type, I think), so this is not
completely safe under C99 (it is safe in the sense that it cannot lead
to undefined behavior, but the results may be inaccurate).
-Kevin