2016-04-16 3 views
1

Скажем, у меня есть указатель на пустоту (больше похоже на массив), и я хочу получить элементы внутри него. Итак, я знаю, что указатель [i] не будет работать, поскольку он недействителен, и я не знаю тип; Я попытался с помощью метода сдвига:C - Указатель и смещение Void

void function(void* p, int eltSize){ 
    int offset = 3; 
    for(i = 0; i<offset; i++){ 
    memcpy(p+(i*eltsize), otherPointer, eltSize);//OtherPointer has same type. 
    } 
    //End function 
} 

Эта функция работает хорошо и все, но единственная проблема в том, что в конце основной (..) Я получаю ошибку сегментации. Я знаю, что это из-за указателя и того, как я обращался к его элементам, но я не знаю, как исправить проблему и избежать ошибки сегментации.

+0

Если вы не знаете, что это (тип) в местоположении адреса, вы не можете его использовать ... – Boiethios

+0

'p + (I * eltsize)' это могло бы вообще не компилироваться. Компилятор не может выполнять арифметику указателей на указателях void. – fluter

+0

@Morovaille, 'qsort' не знает тип и работает. –

ответ

4

Как отметило @sunqingyao и @flutter, вы не можете использовать арифметику с void указателями, вместо этого, используйте char * (кусок байт а-ля qsort):

#include <stdio.h> 
#include <string.h> 

void function(void *ptr, size_t eltSize, void *otherPointer, size_t offset) 
{ 
    char *p = ptr; 

    for (size_t i = 0; i < offset; i++) { 
     memcpy(p + (i * eltSize), otherPointer, eltSize); 
    } 
} 

int main(void) 
{ 
    int arr[] = {1, 2, 3}; 
    int otherValue = 4; 

    function(arr, sizeof *arr, &otherValue, sizeof arr/sizeof *arr); 
    for (int i = 0; i < 3; i++) { 
     printf("%d\n", arr[i]); 
    } 
    return 0; 
} 
+0

Благодарим вас за ответ. Но; что, если ptr указывает на структуру? Должна ли она работать, хотя мы использовали ее как указатель на символ? И я видел много сообщений об этом указателе char *. Не могли бы вы указать на «трюк», используемый здесь (литье void * на char *). Спасибо. – user52713

+0

Нет проблем с использованием 'struct' вместо примитивных типов, посмотрите на [этот поток] (https://bytes.com/topic/c/answers/618725-void-vs-char),' void * 'и 'char *' функционально эквивалентны, ключевым свойством является то, что они являются указателями, которые могут быть точно переданы любому другому типу указателя. Законно выполнять арифметику на 'char *', но не на 'void *'. –

+1

Отлично. Огромное спасибо. попробуем это как можно скорее! – user52713

0

Цитируется N1570 6.5.6 Аддитивные операторы (курсив мой):

2 Для того, либо оба операнда имеют арифметический тип или один операнд должен быть указателем на полный тип объекта и другие должны иметь целочисленный тип. (Инкрементирование эквивалентно добавлению 1.)

Очевидно, что void не полный тип объекта. Таким образом, применение оператора + на void * вызывает неопределенное поведение, которое может привести к ошибке сегментации или чем-либо еще.

Одним из подходов к решению вашей проблемы будет объявление параметра p как char *.

Смежные вопросы