Указатель void void pointer

Даже после литья указателя void, я получаю ошибку компиляции, разыменовывая ее. Может кто-нибудь, пожалуйста, сообщите мне причину этого.

int lVNum = 2;
void *lVptr;
lVptr = (int*)&lVNum;

printf("\nlVptr[60 ] is  %d \n",lVptr[1]);

Ответ 1

printf("\nlVptr[60 ] is %d \n", *(int*)lVptr);

Это приведет к указанию void указателю на int, а затем разыщите его правильно.

Если вы хотите рассматривать его как массив (один), вы можете сделать немного уродливый ((int *)lVptr)[0]. Использование [1] выходит за рамки и, следовательно, не является хорошей идеей (как для lVptr[60]...)

Ответ 2

Не имеет смысла разыменовывать указатель на пустоту. Как компилятор интерпретирует память, на которую указывает указатель? Сначала нужно направить указатель на правильный тип:

int x = *(int*)lVptr;

Ответ 3

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

Вам нужно объявить его как int*.

void *some_ptr = /* whatever */;
int *p = (int*)some_ptr;
// now you have a pointer to int cast from a pointer to void

Обратите внимание, что приведение к int* также не требуется, по той же причине вам не нужно (и не должно) отличать возвращаемое значение malloc в C.

void* может быть неявно преобразован в любой тип указателя и из него. Я добавил актеры только для ясности, в вашем коде, который вы просто напишете;

int *p = some_void_ptr;

Кроме того, это:

lVptr[1]

Неправильно. У вас есть указатель на один int, а не на два. Это разыменование вызывает поведение undefined.

Ответ 4

Вы не можете разыменовывать указатель void, потому что у него нет типа, сначала нужно отбросить его, а затем разыменовать * (int *) lVptr

int lVNum = 2;
void *lVptr;
lVptr = &lVNum;

printf("\nlVptr[60 ] is  %d \n",*(int *)lVptr);

Ответ 5

Указатель void - это просто указатель на пустоту (ничего не определяемый).

Полезно в некоторых случаях. Например, malloc() возвращает указатель на void именно потому, что он выделяет память для цели UNDEFINED. Некоторые функции также могут принимать указатели void как аргументы, поскольку они не заботятся о фактическом содержимом, отличном от местоположения.

Честно говоря, опубликованный вами фрагмент абсолютно не имеет смысла, даже не догадывается, что вы пытались сделать.

Ответ 6

Пример того, что вы пытаетесь сделать:

#include <stdio.h>

int main () {
    void *v;
    unsigned long int *i = (unsigned long int *)v;

    *i = 5933016743776703571;

    size_t j = sizeof(i);
    printf("There are %ld bytes in v\n", j);

    size_t k;
    for (k = 0; k < j; k++) {
        printf("Byte %ld of v: %c\n", k, ((char *)v)[k]);
    }
}

Вывод:

There are 8 bytes in v
Byte 0 of v: S
Byte 1 of v: T
Byte 2 of v: A
Byte 3 of v: C
Byte 4 of v: K
Byte 5 of v: O
Byte 6 of v: V
Byte 7 of v: R

Ответ 7

@Code-Guru  Я попытался скомпилировать его в visual studio. Он дает ошибку - выражение должно быть указателем на полный объект.

Спасибо, teppic, Как вы предположили, следующий компилирует и дает правильный результат.

#include<stdio.h>

void main(){

printf("study void pointers \n");

int lvnum = 2;
void *lvptr;
lvptr = &lvnum;
printf("\n lvptr is %d\n",((int *)lvptr)[0]);


}

Однако, если я попробую printf ( "\n lvptr is% d\n", ((int *) lVptr) [60]); Он компилируется и запускается, но дает случайное число.

Большое спасибо, друзья за все предложения. Извиняется за то, что я назначил указатель void на ненужный указатель int int и ожидал, что он будет разыменован. Однако я должен был отбросить его, когда захочу разыграть его.

Цель фрагмента: В моих источниках я обнаружил ошибку в работе, которая была вызвана аналогичной ситуацией. Напротив, программа не только скомпилировала, но и дала правильные результаты. Причина - это код низкого уровня (без ОС), где память, назначенная указателю void, уже зарезервирована до 60. Но инструмент klocwork не смог разобрать файлы, имеющие этот предел, приводящий к ошибке. Я сделал много мозгового штурма и оказался в чем-то глупом.

Саурабх