爲什麼要使用指向指針的指針

在看大型C工程的時候,經常能看到char ** 甚至 void **這樣指向指針的指針,有很多人都不明白,爲什麼要非得用指向指針的指針

其實總結起來,如果你在函數外定義的指針有內容,或者這個內容只是供調用他的函數使用 ,那麼你完全沒有必要使用void **這樣

的方式來訪問你的數據,只需要void * 這樣的指針就行了,但是當我們需要在函數內部修改外部指針時,那麼這時候就顯的尤爲必要

了,總的來說,使用void ** 是因爲我沒要修改或使用指針,而不僅僅使用指針指向的數據。比如我們看個例子來說明下:

假如我們使用指針作爲參數傳遞給一個函數,並希望返回新的指針值,這個時候是錯誤的

char* ptr = NULL;
function(char* p)
{
    p = malloc(1024);
    //p的內容爲1024個字節的內存起始地址
}
//但是執行到這裏的時候依然是 ptr == NULL;
//並不是我想要得到的結果,說到底,這也是個變量

只有使用指針的指針纔可以實現返回新的指針

char* ptr = NULL;
char** pp= &ptr;
   int function(char** pp)
  {
    *pp = malloc(1024);
      //*pp的內容爲1024個字節的內存起始地址
  }
//執行到這裏的時候 *pp的內容仍然爲ptr的地址;
//但是*ptr的內容已經指向了新分配的1024的內存空間

上面的例子可能只是說明性的例子,可能還是沒有足夠的說服力,來讓你相信有時候沒有指向指針的指針還真的不好辦!

比如在V4l2應用中的代碼:

int catch_Oneframe(uchar **p_fram,__u32 *fameSize) {
    struct v4l2_buffer buf;
    CLEAR (buf);
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    if (-1 == xioctl(m_cameraFd, VIDIOC_DQBUF, &buf)) {
        switch (errno) {
            case EAGAIN:
                return 0;
            case EIO:
                /* Could ignore EIO, see spec. */
                /* fall through */
            default:
                errno_exit("VIDIOC_DQBUF");
        }
    }
    else
    {
        assert(buf.index < n_buffers);
        (*p_fram) = (uchar *)buffers[buf.index].start;
        *fameSize = buffers[buf.index].length;
        //qDebug() << "imagesize is" << framSize << "\n";
    }
    return SUCCESS;
}


這段代碼中我們希望通過在函數外申明一個uchar *fram的指針來指向我們要獲取的一幀圖像,之後申明瞭一個表示這個圖像的大小的int 型變量。而返回值表示我們到底時成功了還是失敗了。所以實際看到的應用是這樣的:
uchar *p_fram = NULL;
unsigned int size = 0,ret = 0;
ret = catch_Onefram(&p_fram,&size);
if(ret)
   transform(p_fram,size);
   //do other img processing 
else
   //return false

有的人會問,可以把函數改寫成返回指針的形式呀,yes,是的可以這樣做,比如改寫成這樣:
uchar * catch_Oneframe(int *return_value,__u32 *fameSize);
這樣改寫函數本身是沒有錯誤的,並且能夠正常的工作,但是在C語言編程時保持鏈式表達的支持,這樣寫會有好處的比如說:
uchar *p_fram = NULL;
unsigned int size = 0,ret = 0;
if(catch_Onefram(&p_fram,&size))
   transform(p_fram,size);
   //do other img processing 
else
   //return false




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章