2015-08-28 3 views
0

Я пытаюсь создать свою собственную функцию свопинга, но у меня проблемы.
Почему я получаю «разыменование указателя пустоты»?C - Указатель разыменования void

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++; 
    } 
} 
+1

обычно, то есть предупреждение компилятора с номером строки, указывающим на точно линии, где это происходит. –

ответ

0

Невозможно разыменовать указатель пустоты. Вы должны привести его к другому типу указателя:

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; 
    } 
} 
+1

Или, лучше, используйте цикл 'for', поэтому управление контуром находится в одной строке. В C99 или C11 вы можете использовать 'for (size_t i = 0; i

2

Вы хотите бросить (абстрактную) void* указатель на указатель на unsigned char так код:

cur_a = (unsigned char *)a + i; 

Ваш код понималось как cur_a = (unsigned char *)(*a) + i; который ошибочно разыменовывает в void* абстрактный указатель.

BTW, ваш *a = cur_b; не имеет смысла ни. Может быть, вы хотите

((unsigned char*)a)[i] = cur_b; 
0
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; 
    } 
} 
2

Поскольку вы разыменование недействительных указателей:

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

Doing *a означает, что вы первое разыменование a, а затем бросил на результате (независимо от того, что is, разыменование void* не имеет смысла) указателю на unsigned char. Производство

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

имеет больше смысла.

+1

За исключением унарных '*' имеет более высокий приоритет, чем '+'. Правильным кодом будет 'cur_a = * ((unsigned char *) a + i);' который является таким же, как '((unsigned char *) a) [i]', но несколько менее читаемым. – aragaer

+0

От этого зависит. Я предположил, что OP хочет добавить числовое значение i в uint8 в a. –

0

Посмотрите ваше заявление

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

если a является указателем к мочеиспусканию (void *a), то *a = void. Затем подвыражение (unsigned char *)*a означает, что вы хотите наложить void на указатель на символ.

Но void означает 'inexistent type' в C, из-за этого ошибки. Вы можете спросить, почему вместо этого указатель на пустоту имеет смысл, это имеет смысл, потому что это адрес, который является допустимым типом данных в 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++; 
    } 
} 
Смежные вопросы