//---- 1. 字符指针可以在定义时直接赋值 //---- 2. 指针在使用前必须先初始化 //---- 3. 通过分配内存给指针赋值,此时指针指向所分配的内存的首地址。 3.1 申请分配内存后,必须检查是否成功。 3.2 指针释放后应该置NULL //---- 4. 指针的增减是以指针类型的字节长度为单位进行的 //---- 5. 指针与数组 5.1 如果int array[3][4],那么array就是一个数组指针,其类型长度为3*4*sizeof(int)=48 5.2 数组指针 : int (*arp)[4] 定义了一个数组指针,arp指向一个含4个int元素的一维数组。 5.3 指针数组 : int *par[4] 定义了一个有4个元素的指针数组, 每个元素是一个整型类指针。 //---- 6.指针的指针 6.1 多重指针定义和赋值 6.2 通过分配内存给多重指针赋值 6.3 释放多重指针所指内存 : 指针释放后应该置NULL
pointer.c
#include <stdio.h> #include <stdlib.h> int main(void) { int i,j,k; int m; //---- 1. 字符指针可以在定义时直接赋值 printf("\n\n ----- 1. Char Pointer Initilization -----\n"); char *pc = "hello world!"; //OK printf( "char pointer pc = %s\n", pc); int *p = 5; // WRONG !!! warning: initialization makes pointer from integer without a cast !!!! printf( " p = %p \n", p); // p = 0x5 //---- 2. 指针在使用前必须先初始化 printf("\n\n ----- 2. Pointer before Init is (nil) -----\n"); int *pa; printf(" int *pa; pointer before init: pa = %p, or the value of pa is %x\n",pa,(unsigned int)pa); // *pa = 1; // WRONG!!! Segmentation fault (core dumped) !!! //---- 3. 通过分配内存给指针赋值,此时指针指向所分配的内存的首地址。 printf("\n\n ----- 3. Pointer and Malloc/Free -----\n"); pa=(int *)malloc(5*sizeof(int)); printf("after malloc 5*sizeof(int), pointer values: \n"); // --- 3.1 申请分配内存后,必须检查是否成功。 for(i=0;i<5;i++) printf("pa[%d]=%d \n",i,pa[i]); printf("pa[6] is out of range, however: "); printf("pa[6]=%d \n",pa[6]); free(pa); //---- 4. 指针的增减是以指针类型的字节长度为单位进行的 printf("\n\n ----- 4. Pointer Type Size -----\n"); for(i=0;i<5;i++) { printf("pa+%d=%p\n",i,pa+i); } /* -- print result,4bytes for sizeof(int) ---- pa+0=0x201b420 pa+1=0x201b424 pa+2=0x201b428 pa+3=0x201b42c pa+4=0x201b430 */ //---- 5. 指针与数组 printf("\n\n ----- 5. Array and Pointer -----\n"); int array[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; for(i=0;i<3;i++) for(j=0;j<4;j++) printf("array[%d][%d]=%d\n",i,j,array[i][j]); int *parray=array; //!!!! warning: initialization from incompatible pointer type !!!! printf("\nint array[3][4]=...;\n\nint *parray=array; \n"); printf("WARNING: initialization from incompatible pointer type!!!\n"); //------5.1 如果int array[3][4],那么array就是一个数组指针,其类型长度为3*4*sizeof(int)=48 printf("!!! sizeof(array)=%ld while sizeof(*parray)=%ld \n\n",sizeof(array),sizeof(*parray)); parray=(int *)array; printf("parray=(int *)array;\n"); printf("parray[9]=%d = array[2][1]=%d \n", parray[9], array[2][1]); //------5.2 数组指针 : int (*arp)[4] 定义了一个数组指针,arp指向一个含4个int元素的一维数组。 printf("\n\n ----- 5.1 Array Pointer: int (*arp)[] [ > ( > * -----\n"); int (*arp)[4]; arp=array; //或 ap= array[0] 或 ap=&array[0][0]; for(i=0;i<4;i++) { printf("(arp+1)[0][%d]=%d\n",i,(arp+1)[0][i]); // arp[2][i] 和 (arp+2)[0][i] 相同! printf("arp[2][%d]=%d ",i,arp[2][i]); printf("(arp+2)[0][%d]=%d\n",i,(arp+2)[0][i]); } //------5.3 指针数组 : int *par[4] 定义了一个有4个元素的指针数组, 每个元素是一个整型类指针。 printf("\n\n ----- 5.2 Pointer Array: int *par[] [ > ( > * -----\n"); int *par[3]; par[0]=(int *)array[0]; //或则 &array[0][0] par[1]=(int *)array[1]; par[2]=(int *)array[2]; for(i=0;i<3;i++) { printf("par[%d]=(int *)array[%d]; ",i,i); printf(" *par[%d] = %d \n", i,*array[i]); //*array[i] 和 array[i][0] 相等*/ } //----- 6.指针的指针 printf("\n\n ----- 6. Pointer to Pointer -----\n"); //-------6.1 多重指针定义和赋值 int var=666; int *ptr; int **pptr; printf("\n\n ----- 6.2 Pointer to Pointer: Assignment -----\n"); printf("var=%d\n",var); // pptr=&(&var); // !!! WRONG !!! & must follows with a variable name. ptr=&var; printf("ptr=&var=%p\n",ptr); pptr=&ptr; printf("pptr=&ptr=%p\n",pptr); printf("\npptr[0] = %p\n", pptr[0]); printf("pptr[0][0] = %d\n", pptr[0][0]); //-------6.2 通过分配内存给多重指针赋值 printf("\n\n ----- 6.2 Pointer to Pointer: Malloc and Free -----\n"); int *** ppptr; //[3][2][2] // ppptr ----> (int **) ----> (int *) ----> (int) // | | | // | | |--> (int) // | |-> (int *) // | // |--> (int **) -- // | // |--> (int **) -- for(m=0;m<50000;m++) //------------- check memory leakage ---------- { //----- malloc for ppptr : pointer to (int **) ppptr=malloc(3*sizeof(int **)); printf("ppptr=malloc(3*sizeof(int **))=%p\n", ppptr); for(i=0;i<3;i++) { //----- malloc for (* ppptr) : pointer to (int *) ppptr[i]=malloc(2*sizeof(int *)); printf("*ppptr: ppptr[%d]=%p \n",i,ppptr[i]); for(j=0;j<2;j++) { //----- malloc for (** ppptr) : pointer to (int) ppptr[i][j]=malloc(2*sizeof(int)); printf("**ppptr: ppptr[%d][%d]=%p \n",i,j,ppptr[i][j]); } } ppptr[2][1][0]=88888; printf("ppptr[2][1][0]=88888 \n"); for(i=0;i<3;i++) for(j=0;j<2;j++) for(k=0;k<2;k++) printf("***ppptr: ppptr[%d][%d][%d]=%d \n",i,j,k,ppptr[i][j][k]); //} //---END test leakage //-------6.3 释放多重指针所指内存 : 指针释放后应该置NULL printf("\n\n ----- 6.3 Free Pointer to Pointer -----\n"); for(i=0;i<3;i++) { for(j=0;j<2;j++) { free(ppptr[i][j]); //---free: ppptr[i][j]=malloc(2*sizeof(int)); ppptr[i][j]=NULL; //printf("ppptr[%d][%d][0] = %d\n",i,j,ppptr[i][j][0]); printf("ppptr[%d][%d] = %p\n",i,j,ppptr[i][j]); if(j == 2-1){ free(ppptr[i]); //---free: ppptr[i]=malloc(2*sizeof(int *)); ppptr[i]=NULL; printf("ppptr[%d] = %p\n",i,ppptr[i]); } } } free(ppptr); //---free: ppptr=malloc(3*sizeof(int **)); ppptr=NULL; printf("ppptr = %p\n",ppptr); } //---END check leakage return 0; } /* --- mem result --- ----- 6.2 Pointer to Pointer and Malloc/Free ----- ppptr=malloc(3*sizeof(int **))=0xaec420 *ppptr: ppptr[0]=0xaec440 **ppptr: ppptr[0][0]=0xaec460 **ppptr: ppptr[0][1]=0xaec480 *ppptr: ppptr[1]=0xaec4a0 **ppptr: ppptr[1][0]=0xaec4c0 **ppptr: ppptr[1][1]=0xaec4e0 *ppptr: ppptr[2]=0xaec500 **ppptr: ppptr[2][0]=0xaec520 **ppptr: ppptr[2][1]=0xaec540 --- proc maps --- 00400000-00402000 r-xp 00000000 08:07 139229 /home/midas-zhou/pointer 00601000-00602000 r--p 00001000 08:07 139229 /home/midas-zhou/pointer 00602000-00603000 rw-p 00002000 08:07 139229 /home/midas-zhou/pointer 00aec000-00b0d000 rw-p 00000000 00:00 0 <<<-------- [heap] 7fa6e50d3000-7fa6e5293000 r-xp 00000000 08:08 792498 /lib/x86_64-linux-gnu/libc-2.23.so 7fa6e5293000-7fa6e5493000 ---p 001c0000 08:08 792498 /lib/x86_64-linux-gnu/libc-2.23.so 7fa6e5493000-7fa6e5497000 r--p 001c0000 08:08 792498 /lib/x86_64-linux-gnu/libc-2.23.so 7fa6e5497000-7fa6e5499000 rw-p 001c4000 08:08 792498 /lib/x86_64-linux-gnu/libc-2.23.so 7fa6e5499000-7fa6e549d000 rw-p 00000000 00:00 0 7fa6e549d000-7fa6e54c3000 r-xp 00000000 08:08 792470 /lib/x86_64-linux-gnu/ld-2.23.so 7fa6e56a3000-7fa6e56a6000 rw-p 00000000 00:00 0 7fa6e56c2000-7fa6e56c3000 r--p 00025000 08:08 792470 /lib/x86_64-linux-gnu/ld-2.23.so 7fa6e56c3000-7fa6e56c4000 rw-p 00026000 08:08 792470 /lib/x86_64-linux-gnu/ld-2.23.so 7fa6e56c4000-7fa6e56c5000 rw-p 00000000 00:00 0 7ffc0fc00000-7ffc0fc21000 rw-p 00000000 00:00 0 [stack] 7ffc0fd7a000-7ffc0fd7d000 r--p 00000000 00:00 0 [vvar] 7ffc0fd7d000-7ffc0fd7f000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] --- Leakage Test ---- VIRT: virtual memory RES: physical memory ( top -d 1 ) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 29063 midas-z+ 20 0 4356 728 660 R 39.2 0.0 0:07.99 pointer */