malloc的意外行为 [英] Unexpected behaviour of malloc

查看:80
本文介绍了malloc的意外行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近使用DevC ++ 4.0,它使用GCC的Mingw端口,在
WinXP上。我很惊讶地看到malloc行为与文档一致并不符合b $ b。查看程序及其输出

以下。


#include< stdio.h>

#include< stdlib。 h>


int main(int argc,char * argv [])

{

char * str1;

char * str2;

str1 =" Hello world";

printf(" str1%d \ n的长度",strlen(str1) ));

str2 =(char *)malloc(strlen(str1));

printf(" str2%d \ n的长度),strlen(str2) ));


strncpy(str2,str1,strlen(str1));

printf("%d \ n之后的str2长度), strlen(str2));

返回0;

}


输出是

长度str1 11

str2的长度3

17之后str2的长度


str2"应该是11.然后如何str2之后的长度是的。


是因为malloc分配了一小部分内存(这里是3)和

后来增长到需求?好的同意,但它的增长远远超出了

的需求(它增长到17而不是11)。


~sraca

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

推荐答案



< si ***** @ gmail.com>在消息中写道

news:89 ************************** @ posting.google.c om ...

<si*****@gmail.com> wrote in message
news:89**************************@posting.google.c om...
我最近在WinXP上使用DevC ++ 4.0,它使用GCC的Mingw端口。我很惊讶地看到malloc行为与文档不一致。请参阅下面的程序及其输出。

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

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


(char *)演员表是不必要的。 #include< stdlib.h>扔掉

cast。

printf("长度为str2%d \ n,strlen(str2));


在单元化字符串上调用strlen(就像你一样)可能会给你* any *

size

仍然是正确的。毕竟,没人知道字符串中有什么。

strncpy(str2,str1,strlen(str1));


由于您提供的strncpy最大长度为11(strlen(Hello

World)),终止''\0'' (表示字符串的结尾)不是复制的
。因此str2不会以零终止,第二个strlen会计入

,直到它遇到''\0''。它可能还打印了任何其他数字,

因为这基本上取决于在str2 +

11之后内存中发生的事情。


尝试使用strlen(str1)+ 1。

printf(%d \ n之后的str2的长度,strlen(str2));


< snip>

根据我对malloc的解释理解,
str2的长度应该是11.


不。 malloc不会在任何地方自动复制任何内容。它是
返回一个* unitialized * chuck of memory(当然还是NULL)。

怎么来str2之后的长度是17.
是因为malloc分配了一小部分内存(这里是3)并且
后来成长为需求?


Nope。

好​​的同意,但它的增长远远超出需求(它增长到17而不是
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



)11)。


由于上述原因。看来你对C的理解还不完整。我建议你买一本关于这个主题的好(教程)书。


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.


-----开始PGP签名的消息-----

哈希:SHA1

si*****@gmail.com 写道:

|我最近使用DevC ++ 4.0,它使用GCC的Mingw端口,在
|上WinXP中。我很惊讶地看到malloc的行为不是
|与文档一致。查看程序及其输出

|下面。

|

| #include< stdio.h>

| #include< stdlib.h>

|

| int main(int argc,char * argv [])

| {

| char * str1;

| char * str2;

| str1 =" Hello world";

| printf("长度为str1%d \ n,strlen(str1));

| str2 =(char *)malloc(strlen(str1));

| printf("长度为str2%d \ n,strlen(str2));

|

| strncpy(str2,str1,strlen(str1));

| printf(%d \ n之后的str2的长度,strlen(str2));

|

|

|返回0;

| }

|

|输出是

| str1的长度11

| str2的长度3

| 17之后str2的长度

|

|根据我对malloc的解释理解,长度

| STR2"应该是11.


不是你计算它的方式,它不应该。


malloc()返回指向未初始化内存的指针你可以

存储一个字符串。


strlen()计算一个字符数组中的字符数,停在,并且

不包括第一个''\ 0''字符。


因为你没有初始化malloc()在你使用之前给你的内存

strlen()来计算字符数,你计算的是非零

字符,它们是字符数组中指向的剩余垃圾。

malloc()返回的值。无法保证在该阵列中的任何位置都会有一个

''\ 0''字符,甚至超出它,并且无法保证

运行 - time会阻止strlen()超出malloc()分配的内存边界。这意味着您可能会计算/超出/

由malloc()分配的内存范围,或者在

内存块内进行简短计数。


换句话说,你的方法是错误的,你的结果是错误的。


你的计算没有预定的''预期结果'' ,所以3是

有效期为11.


|然后怎么说str2之后的长度是17.


见上文。你用相同的设计缺陷搞砸了计算。


另外一个注意事项;在C中,字符串由''\ 0''字符终止,该字符不是由strlen()计算的
。因此,你的str1包含12个字符,即使

strlen()表示有11个字符。


这意味着你的malloc()也是一个字节简短地包含''\ 0''',即你的第三次测试所需的
(之后的长度为str2)才能正常工作。

|是因为malloc分配了最少的一块内存(这里是3)

编号见上面


[snip]


- -

Lew Pitcher

IT顾问,企业数据系统,

企业技术解决方案,道明银行金融集团

(表达的意见是我自己的,不是我的雇主')

----- BEGIN PGP SIGNATURE -----

版本:GnuPG v1.2.4(MingW32)

iD8DBQFBr0WcagVFX4UWr64RAmSXAKCldZ0 / lVk9Gu / Qg / Yq24EezLYSGgCg3Vpy

3uA0cgS7BWXbhV0K7PyR9oU =

= TFwh < br $>
----- END PGP SIGNATURE -----
-----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-----


si ***** @ gmail.com 写道:
我最近在WinXP上使用DevC ++ 4.0,它使用了GCC的Mingw端口。我很惊讶地看到malloc行为与文档不一致。请参阅下面的程序及其输出。

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

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


/ *不要这样做!你还没有初始化str2

指向的内存。您无法保证

分配内存中的任何位置都有''\ 0''。 * /
strncpy(str2,str1,strlen(str1));
printf(%d \ n之后的str2的长度,strlen(str2));


/ *不要这样做!你没有将''\ 0''终止str1复制到str2指向的

内存中。您无法保证在分配的内存中的任何位置都有''\0''

。 * /

返回0;
}

输出是
str1的长度11
str2的长度3
长度17之后的str2
从我对malloc的解释中所理解的,
str2的长度应该是11.


为什么会这样?如果你想要正确终止字符串,

复制终止''\ 0''。


怎么来str2之后的长度 ;这是因为malloc分配了一小块内存(这里是3)


它与malloc无关。 3是一个意外:它可以很容易地获得0或6000000或42.


后来成长为需求?好的,但它的增长远远超出了需求(它增长到17而不是11)。
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).




学习如何做终止的简单事情

涉水到你不明白的奥秘之前。在

printf之前使用

* str2 = 0;

尝试你的代码(str2%d \ n的长度,strlen (str2));



strncpy(str2,str1,strlen(str1));

更改为

strncpy(str2,str1,1 + strlen(str1));



strcpy(str2,str1);



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);


这篇关于malloc的意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆