关于malloc与字符指针的一些易错点
?有如下一段代碼,意圖把“zhongxiaoming"字符串賦值進(jìn)以p為首地址的空間為15字節(jié)的內(nèi)存空間,然后釋放p所指向的內(nèi)存,以免出現(xiàn)內(nèi)存泄露。
該代碼出現(xiàn)幾個問題,涉及到內(nèi)存的賦值、malloc函數(shù)以及free函數(shù)的用法,以及字符串的相關(guān)知識。
?1 #include <stdio.h>
? 2 #include <stdlib.h>? 3?
? 4 int main()
? 5 {
? 6 ? ? ? ? char *p = (char*)malloc(15);
? 7 ? ? ? ? int i=0;
? 8 ? ? ? ? p="zhongxiaoming";
? 9 ? ? ? ? for(;i<15;i++)
?10 ? ? ? ? { ? ? ??
?11 ? ? ? ? ? ? ? ? printf("p[%d]:%c\t",i,*(p+i));
?12 ? ? ? ? }
?13 ? ? ? ? printf("\n");
?14 ? ? ? ? free(p);
?15 ? ? ? ? p=NULL;
?16 ? ? ? ? printf("ok\n");
?17 ? ? ? ? return 0;
?18 }
===================================================================
編譯運(yùn)行后:
Love-Yan:pointertest MD101$ make
gcc -o malloctest malloctest.c -g
Love-Yan:pointertest MD101$ ./malloctest
p[0]:z p[1]:h p[2]:o p[3]:n p[4]:g p[5]:x p[6]:i p[7]:a p[8]:o p[9]:m p[10]:i p[11]:np[12]:g p[13]:p[14]:p
malloctest(3232) malloc: *** error for object 0x107a45f4e: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
可知道,pointer being freed was not allocated。意思是,意圖釋放的指針(p)沒有被分配,這是什么意思呢?明明malloc了15字節(jié)的空間,怎么說沒有被分配呢?
原來:??
malloc========================================
8 ? ? ? ? p="zhongxiaoming"; 這行語句打亂了所有的計(jì)劃,導(dǎo)致分配出來的15字節(jié)空間丟失了,內(nèi)存泄露掉了。
?6 ? ? ? ? char *p = (char*)malloc(15);這時候的p才是15字節(jié)的真正主人。
按照本意,我們采用strcpy就可以把“zhongxiaoming”拷貝進(jìn)p指向的內(nèi)存。不過,要記得加進(jìn)<string.h>頭文件哦。具體代碼:
strcpy(p,"zhongxiaoming");這樣,p對應(yīng)的連續(xù)15個內(nèi)存地址就依次被賦值了,當(dāng)然,只是賦值了strlen(“zhongxiaoming”)+1個字節(jié),后面的應(yīng)該保持不變,因?yàn)閙alloc分配出來的空間不會對內(nèi)存進(jìn)行初始化,而new操作符分配出來的會初始化。
字符串、內(nèi)存靜態(tài)區(qū)======================================
第八行代碼把在靜態(tài)區(qū)創(chuàng)建的字符串常量“zhongxiaoming”的首地址賦值給了p,此時,指針變量p的值發(fā)生了變化,不再是指向15個字節(jié)的首地址了。
此時,可以通過p對字符串常量進(jìn)行讀的操作(無寫操作,字符常量不允許修改,通常在靜態(tài)區(qū)的內(nèi)容,很多都是字符常量、整形常量等等,譬如int a=12;doule b=123.123123;
這里的12和123.123123都是放在靜態(tài)區(qū)的,他們都有個地址,這些常量與a、b對應(yīng),讀a也就是讀a對應(yīng)的12.可是如果再有對a 的重新賦值,則常量區(qū)的12將會在某個時刻被系統(tǒng)回收掉,可以肯定的是,程序結(jié)束后肯定被釋放掉了,呵呵。。。重新賦值a,如a=12312,則又在靜態(tài)區(qū)創(chuàng)建12312與a對應(yīng),以此類推。),在此特別引申一點(diǎn):
指針對應(yīng)的字符串的訪問還可以通過poiner[i]操作符進(jìn)行訪問。當(dāng)然,在這里是想把“zhongxiaoming”全部讀出來。而p又指向其對應(yīng)的地址(其實(shí),用&(“zhongxiaoming”)可得到其地址),故我們可以通過p[i]進(jìn)行訪問,當(dāng)然了,不能寫哦,常量嘛,靜態(tài)區(qū)嘛。。。那我們就這樣完成了對常量區(qū)字符串“zhongxiaoming”的讀操作啦。當(dāng)然,這是沒有修改過的源代碼的功能。
free===================================================
按照沒有修改過的源代碼,直接就free(p),也太夸張了吧,把p(也就是&(“zhongxiaoming”)對應(yīng)的內(nèi)存釋放),這是要逆天了?想去釋放靜態(tài)區(qū)的內(nèi)存。。嘿嘿,這可是系統(tǒng)自己的事,最好還是別干預(yù)了。所以,系統(tǒng)報錯。。。說,malloctest(2617) malloc: *** error for object 0x107b27f48: pointer being freed was not allocated。也就是說,這不是你分配的內(nèi)存,這段內(nèi)存不歸你管。。。
修改代碼==================================================
而加入strcpy的新代碼,要對p對應(yīng)的內(nèi)容進(jìn)行訪問也就是有【】操作符或者*(p+i)了,千萬別寫成&p+i哦,這樣子可是會挎了15個字節(jié)訪問了哦。。。我們把代碼修改下:
#include <stdio.h>
? 2 #include <stdlib.h>
? 3 #include <string.h>
? 4 int main()
? 5 {
? 6 ? ? ? ? char *p = (char*)malloc(15);
? 7 ? ? ? ? int i=0;
? 8 ? ? ? ? memset(p,'A',15);
? 9 ? ? ? ? for(;i<15;i++)
?10 ? ? ? ? { ? ? ? ? ? ? ?
?11 ? ? ? ? ? ? ? ? ?printf("p[%d]:%c\t",i,p[i]);
?12 ? ? ? ? }
?13 ? ? ? ? printf("\n\n");
?14 ? ? ? ??
?15 ? ? ? ? strcpy(p,"zhongxiaoming");
?16 ? ? ? ? for(i=0;i<15;i++)
?17 ? ? ? ? { ? ? ??
?18 ? ? ? ? ? ? ? ? printf("p[%d]:%c\t",i,p[i]);
?19 ? ? ? ? }
?20 ? ? ? ? printf("\n");
?21 ? ? ? ? free(p);
?22 ? ? ? ? p=NULL;
?23 ? ? ? ? return 0;
?24 }
運(yùn)行:
Love-Yan:pointertest MD101$ make
gcc -o malloctest malloctest.c -g
Love-Yan:pointertest MD101$ ./malloctest
p[0]:z p[1]:h p[2]:o p[3]:n p[4]:g p[5]:x p[6]:i p[7]:a p[8]:o p[9]:m p[10]:i p[11]:n p[12]:g p[13]: p[14]:
Love-Yan:pointertest MD101$?
大功告成。。。
不過,在這里,如果要考究下strcpy對p的15個字節(jié)處理了多少個呢?我們可以先用memset來對這15個字節(jié)進(jìn)行下初始化,然后再輸出看看就知道了。
Love-Yan:pointertest MD101$ make
gcc -o malloctest malloctest.c -g
Love-Yan:pointertest MD101$ ./malloctest
p[0]:A p[1]:A p[2]:A p[3]:A p[4]:A p[5]:A p[6]:A p[7]:A p[8]:A p[9]:A p[10]:A p[11]:Ap[12]:A p[13]:Ap[14]:A
p[0]:z p[1]:h p[2]:o p[3]:n p[4]:g p[5]:x p[6]:i p[7]:a p[8]:o p[9]:m p[10]:i p[11]:np[12]:g p[13]:p[14]:A
Love-Yan:pointertest MD101$?
good news。。。只是對前面的部分字節(jié)進(jìn)行了賦值。可是第十四了也就是p[13]里邊的內(nèi)容是空的。。這是怎么回事?
我們知道字符串的結(jié)尾是'\0‘對吧,里邊會不會就是'\0'呢?我們可以gdb一下。看看這個p[13]是什么。
果然。。。
(gdb) p p[13]
$2 = 0 '\0'
(gdb)?
轉(zhuǎn)載于:https://www.cnblogs.com/iosDevZhong/p/4395242.html
總結(jié)
以上是生活随笔為你收集整理的关于malloc与字符指针的一些易错点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows下hadoop配置
- 下一篇: 学习微积分60年有感(I)