簡體   English   中英

C-取消引用空指針

[英]C - Dereferencing void pointer

我正在嘗試創建自己的交換函數,但遇到了麻煩。
為什么我會“取消引用空指針”?

void    ft_swap(void *a, void *b, size_t nbytes)
{
    unsigned char   *cur_a;
    unsigned char   *cur_b;
    size_t          i;

    i = 0;
    while (i < nbytes)
    {
        cur_a = (unsigned char *)*a + i; // here
        cur_b = (unsigned char *)*b + i; // here

        *a = cur_b;
        *b = cur_a;

        i++;
    }
}

您想要將(抽象的) void*指針轉換為指向unsigned char的指針,因此代碼如下:

cur_a = (unsigned char *)a + i;

您的代碼被理解為cur_a = (unsigned char *)(*a) + i; 錯誤地取消引用void*抽象指針。

順便說一句,您的*a = cur_b; 也沒有任何意義。 也許你想要

((unsigned char*)a)[i] = cur_b;

因為您要取消引用空指針:

void    ft_swap(void *a, void *b, size_t nbytes)
{
 ...
        cur_a = (unsigned char *)*a + i; // here
        cur_b = (unsigned char *)*b + i; // here

進行*a意味着您首先解除對a引用,然后將結果(無論如何,對void*引用都沒有多大意義)投射到一個指向unsigned char的指針。

cur_a = *((unsigned char *)a) + i;

更有意義。

不允許取消引用void指針。 您需要將其強制轉換為另一種指針類型:

cur_a = (unsigned char *)a;

同樣,您不能將任何內容分配給*a 正確的代碼是:

void ft_swap(void *a, void *b, size_t nbytes) {
    unsigned char  *cur_a = (unsigned char *) a;
    unsigned char  *cur_b = (unsigned char *) b;

    for (size_t i = 0; i < nbytes; ++i) {
        unsigned char tmp = cur_a[i];
        cur_a[i] = cur_b[i];
        cur_b[i] = tmp;
    }
}
    cur_a = (unsigned char *)*a + i; // here
                             ^^^ that is dereferencing a void*

    cur_b = (unsigned char *)*b + i; // here
                             ^^^ that is dereferencing a void* also.

在行中:

    *a = cur_b;
    *b = cur_a;

您也在取消引用void*

這是我建議修復的功能:

void ft_swap(void *a, void *b, size_t nbytes)
{
   unsigned char* cpa;
   unsigned char* cpb;
   size_t          i;
   unsigned char c;

   cpa = (unsigned char *)a;
   cpb = (unsigned char *)b;

   for ( i = 0; i < nbytes; ++i )
   {
      c = cpa[i];
      cpa[i] = cpb[i];
      cpb[i] = c;
   }
}

看你的陳述

cur_a = (unsigned char *)*a + i; // here

如果a是指向void( void *a )的指針,則*a = void 然后,子表達式(unsigned char *)*a表示您想將void轉換為char的指針。

但是void在C中表示“不合理的類型” ,由此產生錯誤。 您可能會問,為什么指向void的指針更有意義,因為它是一個地址,這在C語言中是有效的數據類型,所以很有意義。您可以將地址用於所有不涉及指針類型的操作。 即,將地址分配給指向任何數據類型的指針,反之亦然。 a[2]這樣的表達式是非法的,其中下標運算符[]需要指向數據的大小來計算在哪里獲取值的地址。 當然,虛假類型的void沒有大小(因為它缺少許多其他屬性)。

說,我可以得出結論,這只是代碼中的錯誤,而您真正想要做的是:

void    ft_swap(void *a, void *b, size_t nbytes)
{
    unsigned char   cur_a;    //value not pointers
    unsigned char   cur_b;
    size_t          i;

    i = 0;
    while (i < nbytes)
    {
        cur_a = *((unsigned char *)a + i); // here
        cur_b = *((unsigned char *)b + i); // here

        *a = cur_b;
        *b = cur_a;

        i++;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM