⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 badalloc2.html

📁 this is a mirrored site c-faq. thought might need offline
💻 HTML
字号:
<html><!-- &lt;2004May25.2101.scs.0024@artichoke.scs.ndip.eskimo.net&gt; --><!-- Mirrored from c-faq.com/malloc/badalloc2.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 08:02:58 GMT --><head><title></title></head><body><p>[Someone asked me why after invoking<pre>	p = malloc(1);</pre>it was apparently possible to copy long strings --much longer than 1 byte long --to <TT>p</TT>.This was my reply.]<p>There are several different answers here, depending on just whatit is you're trying to ask.<p>It sounds like you're aware of the reasons the program might not work.You're right, it might not work, it can't be expected to work.If, based on the fact that the program &ldquo;just happens&rdquo; to work,you're tempted to conclude that those other reasons were wrong,don't do this!  The program is definitely wrong.  But there's anunfortunate paradox about software testing: if a program does notwork, it definitely has a bug of some sort, but if on the otherhand it seems to work, we can <em>not</em> conclude from this that ithas no bugs!<p>Another way of answering the question is this: You are walkingalong a deserted street at 3:00 in the morning.  You come to anintersection.  The light is red, and the sign says &ldquo;Don't Walk&rdquo;.You decide to cross the street anyway, even though this isIllegal and Wrong.  As you cross the street, you are not hit bya car, and no policeman arrests you -- you reach the other sideunscathed.  Why?<p>Or, as Roger Miller has written, &ldquo;Somebody told me that inbasketball you can't hold the ball and run.  I got a basketballand tried it and it worked just fine.  He obviously didn'tunderstand basketball.&rdquo;<p>If you want to understand at a low level how the program couldwork, in spite of its egregious error, the explanation isactually not too far from the traffic light parable above.You asked <TT>malloc</TT> for a pointer to 1 byte of memory.  <TT>malloc</TT> gaveyou such a pointer, but your computer certainly has more than 1byte of memory available, so the pointer <TT>malloc</TT> gives you pointssomewhere in the middle of all the memory your program hasavailable to it.  You're only <em>supposed</em> to write 1 byte to thememory <TT>malloc</TT> &ldquo;gave&rdquo; you, because that's all you asked for, butthere's memory sitting there beyond the 1 byte you asked for, andthere's no mechanism, no policeman which will immediately noticeand complain if you write more than you should.<p>(Perhaps a better analogy is this.  Your mother and father run ageneral store.  One day you ask your mother for a dollar.  Yourmother trusts you, so she says you can go to the cash register atthe front of the store and take a dollar out of it.  You open thedrawer of the cash register, and there's $500 in there.  Whathappens if you take more, much more, then the single dollar youwere entrusted to take?  You might get caught eventually, but youprobably won't get caught right away.)<p>If you want to convince yourself that writing more to a malloc'edregion than you're supposed to is wrong, if you want to see thekind of errors that typically arise if you do, you'll need aprogram that tries to do a bit more, after it makes its mistake,so that you and/or the computer and/or the malloc library willhave a chance to notice that things are going wrong.  Forexample, you can malloc two pointers, and notice that when youoverflow one of them, the second string is (probably) affected:<p><pre>	#include &lt;stdio.h&gt;	#include &lt;stdlib.h&gt;	#include &lt;string.h&gt;	int main()	{		char *p1 = malloc(1);		char *p2 = malloc(20);		strcpy(p2, "Hello, world!");		printf("p2 = \"%s\"\n", p2);		strcpy(p1, "This is more than I should write to one byte");		printf("p1 = \"%s\"\n", p1);		printf("p2 = \"%s\"\n", p2);		return 0;	}</pre><p>Or, you can copy some huge number of characters:<p><pre>	#include &lt;stdio.h&gt;	#include &lt;stdlib.h&gt;	#include &lt;string.h&gt;	int main()	{		char *p1 = malloc(1);		char *p2 = malloc(1);		memcpy(p1, p2, 1000000);		return 0;	}</pre><p>I have tested both of these programs on my computer, and theyfail as expected (though I can't promise they'll fail, or in thesame way, for you).<p>Another way to notice when things are going wrong with malloc'edmemory is to <em>always</em> check the return value from <TT>malloc</TT>.It's tempting not to check the return value, especially whenyou're allocating a small amount of memory, and in factI myself succumbed to the temptation in the two programs above.After all, as we just pointed out, our computer certainly hasmore than one byte of memory in it, so a call to <TT>malloc(1)</TT> can&ldquo;never&rdquo; fail, right?  Well, no, actually it can.  <TT>malloc</TT> willtypicallyalso return NULL if it notices that you've written more than youwere supposed to to one of the pointers it previously gave you.So you should <em>always</em> check malloc's return value.  (And,anyway, some day you might actually run out of memory.)So here is one more test program:<p><pre>	#include &lt;stdio.h&gt;	#include &lt;stdlib.h&gt;	#include &lt;string.h&gt;	int main()	{		char *p1, *p2;		p1 = malloc(1);		if(p1 == NULL)			{			fprintf(stderr, "malloc failed\n");			exit(EXIT_FAILURE);			}		strcpy(p1, "This is more than I should write to one byte");		printf("p1 = \"%s\"\n", p1);		p2 = malloc(1);		if(p2 == NULL)			{			fprintf(stderr, "second malloc failed\n");			exit(EXIT_FAILURE);			}		printf("p1 = \"%s\"\n", p1);		*p2 = 'X';		printf("p1 = \"%s\"\n", p1);		return EXIT_SUCCESS;	}</pre><p>I expected that the second call to <TT>malloc</TT> would fail, due to thefact that I copied more text to <TT>p1</TT> than I was supposed to.  Forsome reason, on my computer, the second call to malloc actuallysucceeded, but there's a good chance it will fail on yours.</body><!-- Mirrored from c-faq.com/malloc/badalloc2.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 08:02:58 GMT --></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -