473,401 Members | 2,146 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,401 software developers and data experts.

Unexpected behaviour of malloc

I am using DevC++ 4.0 lately, which uses Mingw port of GCC, on a
WinXP. I am surprised to see the malloc behaviour which is not
consistent with the documentation. See the program and its output
below.

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

int main(int argc, char *argv[])
{
char *str1;
char *str2;
str1 = "Hello world";
printf("Length of str1 %d\n", strlen(str1));
str2 = (char *) malloc(strlen(str1));
printf("Length of str2 %d\n", strlen(str2));

strncpy(str2, str1, strlen(str1));
printf("Length of str2 after %d\n", strlen(str2));
return 0;
}

Output is
Length of str1 11
Length of str2 3
Length of str2 after 17

From what i understand from the explanation of malloc, "Length of
str2" should be 11. And how come "Length of str2 after" is 17.

Is it because malloc allocates a minimum chunk of memory (3 here) and
later grow to the demand? Ok agreed, but it grows well beyond the
demand (It grows up to 17 instead of 11).

~saraca
Nov 14 '05 #1
10 1771

<si*****@gmail.com> wrote in message
news:89**************************@posting.google.c om...
I am using DevC++ 4.0 lately, which uses Mingw port of GCC, on a
WinXP. I am surprised to see the malloc behaviour which is not
consistent with the documentation. See the program and its output
below.

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

int main(int argc, char *argv[])
{
char *str1;
char *str2;
str1 = "Hello world";
printf("Length of str1 %d\n", strlen(str1));
str2 = (char *) malloc(strlen(str1));
The (char *) cast is unneccesary. #include <stdlib.h> and throw away the
cast.
printf("Length of str2 %d\n", strlen(str2));
Invoking strlen on an unititialized string (as you do) may give you *any*
size
and still be correct. Nobody knows what's in the string, after all.
strncpy(str2, str1, strlen(str1));
Since you provided strncpy with a maximum length of 11 (strlen("Hello
World")), the terminating '\0' (which denotes the end of the string) is not
copied. Hence str2 is not zero-terminated and the second strlen will count
until it encounters a '\0'. It might aswell have printed any other number,
since that basically depends on what happens to be in memory after str2 +
11.

Try strlen(str1) + 1 instead.
printf("Length of str2 after %d\n", strlen(str2));
<snip>
From what i understand from the explanation of malloc, "Length of
str2" should be 11.
Nope. malloc does not automathemagically copy any contents anywhere. It
returns an *unitialized* chuck of memory (or NULL, of course).
And how come "Length of str2 after" is 17. Is it because malloc allocates a minimum chunk of memory (3 here) and
later grow to the demand?
Nope.
Ok agreed, but it grows well beyond the demand (It grows up to 17 instead

of 11).

For the reasons mentioned above. It seems your understanding of 'C' is not
yet complete. I would suggest to buy a good (tutorial) book on the subject.
Nov 14 '05 #2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

si*****@gmail.com wrote:
| I am using DevC++ 4.0 lately, which uses Mingw port of GCC, on a
| WinXP. I am surprised to see the malloc behaviour which is not
| consistent with the documentation. See the program and its output
| below.
|
| #include <stdio.h>
| #include <stdlib.h>
|
| int main(int argc, char *argv[])
| {
| char *str1;
| char *str2;
| str1 = "Hello world";
| printf("Length of str1 %d\n", strlen(str1));
| str2 = (char *) malloc(strlen(str1));
| printf("Length of str2 %d\n", strlen(str2));
|
| strncpy(str2, str1, strlen(str1));
| printf("Length of str2 after %d\n", strlen(str2));
|
|
| return 0;
| }
|
| Output is
| Length of str1 11
| Length of str2 3
| Length of str2 after 17
|
| From what i understand from the explanation of malloc, "Length of
| str2" should be 11.

Not the way you compute it, it shouldnt.

malloc() returns a pointer to an uninitialized piece of memory that you can
store a string in.

strlen() counts the number of characters in a character array, stopping at, and
excluding the first '\0' character.

Since you don't initialize the memory that malloc() gives you before you use
strlen() to count the number of characters, you are counting the non-zero
characters that are the residual garbage in the character array pointed to by
the value that malloc() returned. There is no guarantee that there will be a
'\0' character anywhere in that array, or even beyond it, and no guarantee that
the run-time will prevent strlen() from exceeding the bounds of the memory that
was allocated by malloc(). This means that you are potentially counting /beyond/
the confines of the memory allocated by malloc(), or counting short within the
memory block.

In other words, your method is wrong, and your results are wrong because of it.

There is no predetermined 'expected results' for your computation, so 3 is as
valid as 11.

| And how come "Length of str2 after" is 17.

See above. You fouled up the computation with the same design flaw.

One further note; in C, strings are terminated by a '\0' character that isn't
counted by strlen(). Thus, your str1 contains 12 characters, even though
strlen() says that there are 11.

This means that your malloc() is one byte too short to contain the '\0' that's
needed for your third test ("Length fo str2 after") to work properly.
| Is it because malloc allocates a minimum chunk of memory (3 here)
No. See above

[snip]

- --
Lew Pitcher
IT Consultant, Enterprise Data Systems,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFBr0WcagVFX4UWr64RAmSXAKCldZ0/lVk9Gu/Qg/Yq24EezLYSGgCg3Vpy
3uA0cgS7BWXbhV0K7PyR9oU=
=TFwh
-----END PGP SIGNATURE-----
Nov 14 '05 #3
si*****@gmail.com wrote:
I am using DevC++ 4.0 lately, which uses Mingw port of GCC, on a
WinXP. I am surprised to see the malloc behaviour which is not
consistent with the documentation. See the program and its output
below.

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

int main(int argc, char *argv[])
{
char *str1;
char *str2;
str1 = "Hello world";
printf("Length of str1 %d\n", strlen(str1));
str2 = (char *) malloc(strlen(str1));
printf("Length of str2 %d\n", strlen(str2));
/* DON'T DO THIS! You have not initialized the memory to which str2
points. You have no guarantee that there is a '\0' anywhere in the
allocated memory. */
strncpy(str2, str1, strlen(str1));
printf("Length of str2 after %d\n", strlen(str2));
/* DON'T DO THIS! You have not copied the '\0' terminating str1 into the
memory to which str2 points. You have no guarantee that there is a '\0'
anywhere in the allocated memory. */

return 0;
}

Output is
Length of str1 11
Length of str2 3
Length of str2 after 17

From what i understand from the explanation of malloc, "Length of
str2" should be 11.
Why should it be? If you want the string to be terminated properly,
copy the terminating '\0'.

And how come "Length of str2 after" is 17.
Is it because malloc allocates a minimum chunk of memory (3 here)
It has nothing to do with malloc. The 3 is an accident: it could have
been 0 or 6000000 or 42 as easily.
and
later grow to the demand? Ok agreed, but it grows well beyond the
demand (It grows up to 17 instead of 11).


Learn how to do the simple thing of terminating strings properly before
wading into arcana that you don't understand. Try your code with
*str2 = 0;
before the
printf("Length of str2 %d\n", strlen(str2));
and with
strncpy(str2, str1, strlen(str1));
changed to
strncpy(str2, str1, 1+strlen(str1));
or
strcpy(str2, str1);
Nov 14 '05 #4
<si*****@gmail.com> wrote in message
news:89**************************@posting.google.c om...
I am using DevC++ 4.0 lately, which uses Mingw port of GCC, on a
WinXP. I am surprised to see the malloc behaviour which is not
consistent with the documentation. See the program and its output
below.

#include <stdio.h>
#include <stdlib.h>
#include <string.h> as well !

int main(int argc, char *argv[])
{
char *str1;
char *str2;
str1 = "Hello world";
const char *str1 would be advisable, but the standard is lame, and the compiler
defaults favor sloppiness.
printf("Length of str1 %d\n", strlen(str1));
str2 = (char *) malloc(strlen(str1));
Three (!) regulars pointed out the unnecessary cast, but none noticed that the
size is one byte too short !
str2 = strdup(str1); is what the OP wants, but the C99 people were too lame to
introduce useful de facto standard stuff into the standard instead of
martyrizing flies with tons of int*_t types, iso646.h crap, fucking digraphs,
zillions of stupid PRI*** and SCN*** macros...
printf("Length of str2 %d\n", strlen(str2));
Of course str2 points to uninitialized memory, so this is undefined behaviour
strncpy(str2, str1, strlen(str1));
Here we go again : it is a miracle, there is nothing wrong with this gem !
except the OP has no clue about the consequences, and I am getting tired of
explaining why strncpy should be deprecated altogether. NEVER USE strncpy !
printf("Length of str2 after %d\n", strlen(str2));
strlen(str2) yields undefined behaviour.
return 0;
}

Output is
Length of str1 11
Length of str2 3
Length of str2 after 17


It could just as well crash !

--
Chqrlie.
Nov 14 '05 #5
#include <stdio.h>
#include <stdlib.h>
#include <string.h> as well !


I was going to comment on this as well. The OP's code seems to have compiled
ok without the header, but how? Is this (handling library includes) totally
implementation specific?

printf("Length of str1 %d\n", strlen(str1));
str2 = (char *) malloc(strlen(str1));


Three (!) regulars pointed out the unnecessary cast, but none noticed that

the size is one byte too short !


I think Lew Pitcher discussed that at the bottom of his post. It's an
important point to mention though.
Nov 14 '05 #6
Method Man wrote:
#include <stdio.h>
#include <stdlib.h>


#include <string.h> as well !

I was going to comment on this as well. The OP's code seems to have compiled
ok without the header, but how? Is this (handling library includes) totally
implementation specific?


No, just stupid. The headers only contain declarations, no definitions
(usually recommended practice at least). The libraries are linked in
later. If there then is no prototype for a function in scope the
compiler generates code as if the function was declared to return int
(regardless of what it actually returns) and takes arguments with the
types of the actul arguments (regardless of what the formal arguments
are).

This is stupid, has always been stupid and will always be stupid. So
this no longer happens in the newest standard (which hardly anyone
implements).

--
Thomas.
Nov 14 '05 #7

"Charlie Gordon" <ne**@chqrlie.org> wrote in message
news:co**********@reader1.imaginet.fr...

<snip>
printf("Length of str1 %d\n", strlen(str1));
str2 = (char *) malloc(strlen(str1));
Three (!) regulars pointed out the unnecessary cast, but none noticed that

the size is one byte too short !


Not sure wether you count me as a "regular", but I did notice. I should have
commented on it more clearly, though, instead of merely writing "Try
strlen(str1) + 1". After all, the "target audience" in this case is an
obvious newbie. So the criticism is entirely in order and appreciated.
Nov 14 '05 #8
On Fri, 3 Dec 2004 04:56:39 -0500, Method Man
<a@b.c> wrote:
> #include <stdio.h>
> #include <stdlib.h>


#include <string.h> as well !


I was going to comment on this as well. The OP's code seems to have compiled
ok without the header, but how? Is this (handling library includes) totally
implementation specific?


Some implementations have lots of functions in stdlib.h which are also
defined elsewhere (often using a system-specific include file which is
included by both stdlib.h and other headers). At least one version of
GCC, for instance, also pulls in stdint.h within stdlib.h (via one of
the system headers it needs). stdio.h also often pulls in string.h (and
very often pulls in stdlib.h), and lots of things pull in limits.h and
stddef.h (and NULL gets defined all over the place).

You can't guarantee that you get /only/ the functions etc. the standard
says are in a particular header, you should be able to guarantee that
you get /at least/ those functions. In particular memory functions get
included often in both string.h (many traditional compilers had them
there) and in stdlib.hi (it's odd that the memory allocation functions
and the string conversion functions are in stdlib.h but the copy and
comparison functions are in string.h, some implementors just put both
sets in both headers).

Chris C
Nov 14 '05 #9
Chris Croughton wrote:
.... snip ...
Some implementations have lots of functions in stdlib.h which are also
defined elsewhere (often using a system-specific include file which is
included by both stdlib.h and other headers). At least one version of
GCC, for instance, also pulls in stdint.h within stdlib.h (via one of
the system headers it needs). stdio.h also often pulls in string.h (and
very often pulls in stdlib.h), and lots of things pull in limits.h and
stddef.h (and NULL gets defined all over the place).


Not if the system is compliant. Then no functions not listed in
the standard as being defined in that header will appear (with the
exception of names in the implementors namespace, which is why you
don't use such names).

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #10
Groovy hepcat si*****@gmail.com was jivin' on 2 Dec 2004 08:23:51
-0800 in comp.lang.c.
Unexpected behaviour of malloc's a cool scene! Dig it!
printf("Length of str1 %d\n", strlen(str1)); ^^ ^^^^^^^^^^^^
In addition to what others have told you, this line is wrong.
strlen() returns a size_t, an implementation defined unsigned integer
type; but you use a %d conversion specifier, which requires a signed
int argument. Instead, either cast the strlen() call to int or, better
still, cast it to unsigned long (to be sure you don't lose precision)
and use the %lu conversion specifier.

printf("Length of str1 %lu\n", (unsigned long)strlen(str1));
str2 = (char *) malloc(strlen(str1));
printf("Length of str2 %d\n", strlen(str2)); ^^ ^^^^^^^^^^^^
Same here.
strncpy(str2, str1, strlen(str1));
printf("Length of str2 after %d\n", strlen(str2));

^^ ^^^^^^^^^^^^
And here.

--

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"?
Nov 14 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Gerhard Esterhuizen | last post by:
Hi, I am observing unexpected behaviour, in the form of a corrupted class member access, from a simple C++ program that accesses an attribute declared in a virtual base class via a chain of...
8
by: Joona I Palaste | last post by:
We all know that this: void *p; if (p=malloc(1)) { free(p); p; } causes undefined behaviour if malloc() succeeds. But what about this?
9
by: Jeff Louie | last post by:
In C# (and C++/cli) the destructor will be called even if an exception is thrown in the constructor. IMHO, this is unexpected behavior that can lead to an invalid system state. So beware! ...
7
by: KS | last post by:
I have taken up C++ after about 4 years with Java and I am facing a problem with the code that I have written. The problem is that the execution unexpectedly terminates without any error or dump....
2
by: kranthi kumar Adari | last post by:
Hi, After deallocating dynamically allocated memory, I was still accessible to access the data present in that memory. Can u please help me out why this is happening. This happened with c++(new...
23
by: gu | last post by:
hi to all! after two days debugging my code, i've come to the point that the problem was caused by an unexpected behaviour of python. or by lack of some information about the program, of course!...
3
by: nvr | last post by:
Hi all I am doing the socket programming for the client side. but the code is not compiling and i am getting the below error ./Clientsend.c: line 11: syntax error near unexpected token `('...
14
by: leptone | last post by:
Dear all, I am programming a PLC with an 80188 processor, hence I am using an old version of Borland C++ (3.10). While doing the job, I've encountered strange behaviours and I've isolated the...
11
by: Pranav | last post by:
The Code is compiling without Error/Bug/Exception.., What are the possibilities for this behaviour? //*************************************************************** #include<stdio.h> typedef...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.