2015-01-24 1 views
1

как новичок в C, я боюсь проблемы с неясной проблемой, и поскольку я не мог найти решение этой проблемы, я хочу спросить вас следующее: В настоящее время Я пытаюсь понять указатели void и их арифметические операции. Я попытался написать обобщенную функцию, которая принимает указатель пустот в массив, длина массива и размер одного элемента и разбивает данный массив на две части (list1 и List2):Как разбить общий массив пустот на parts.c

void split(void *array, int arrlen, int objsize) 
{ 
// divide the arrlen and save the values 
    int len_list1 = arrlen/2; 
    int len_list2 = arrlen - len_list1; 

// Allocate memory for two temporary lists 
    void *list1 = (void*)malloc(objsize * len_list1); 
    void *list2 = (void*)malloc(objsize * len_list2); 

    if (list1 == NULL || list2 == NULL) 
    { 
     printf("[ERROR]!\n"); 
     exit(-1); 
    } 

// list1 gets initialized properly with int and char elements 
    memmove(list1, array, len_list1*objsize);   
    printf("list1:"); 
    print_arr(list1, len_list1); 

// memmove((char*)list2, (char*)array+list_1_length, list_2_length*objsize); (*) 
    memmove(list2, (int*)array+len_list1, len_list2*objsize); 
    printf("list2:"); 
    print_arr(list2, len_list2); 
} 

Моя проблема заключается в следующем: Если я даю эту функцию в целочисленный массив будет работать нормально, но если я позвоню раскол() с массив символов в качестве аргумента, я должен ...

memmove((char*)list2, (char*)array+list_1_length, list_2_length*objsize); 
//memmove((int*)list2, (char*)array+list_1_length, list_2_length*objsize); 

комментарий line (*) out, чтобы иметь те же результаты. Решение, безусловно, может быть, чтобы написать если-нибудь условие и проверить objsize:

if (objsize == sizeof(int)) 
    // move memory as in the 1st code snippet 
else 
    // move memory with the (int*) cast 

Но с этим решением я хотел бы также проверить другие типы данных, так что это было бы очень мило с вашей стороны, чтобы дать мне намек.

Спасибо!

-matzui

+0

В качестве дополнительной информации для читателей, есть несколько других серьезных недостатков в вашем фрагменте кода. Во-первых, у C нет никакой сборки мусора, поэтому вы ** должны ** использовать 'free' в' list1' и 'list2' после того, как вы закончите с ними. Кроме того, 'memmove' может пригодиться, но когда вы копируете данные в блоки памяти, которые только что были выделены, у вас есть гарантия, что' array', 'list1' и' list2' не будут перекрываться, поэтому вы должны использовать 'memcpy' (из 'string.h') здесь. Пожалуйста, рассмотрите мое редактирование на свой пост. – dummydev

ответ

2
memmove(list2, (int*)array+len_list1, len_list2*objsize); 

Здесь типаж array к int *, и добавить len_list1 к нему. Но добавление чего-то к указателю означает, что он будет умножен на размер одного элемента типа данных этого указателя. Поэтому, если int составляет 4 байта, и вы добавляете 5 к переменной int *, она будет перемещать 20 байтов.

Поскольку вы точно знаете, сколько байтов вы хотите переместить указатель, вы можете указать char * (char = 1 байт) и добавить к нему количество байтов.

Таким образом, вместо (int*)array+len_list1, вы можете использовать (char*)array+(len_list1*objsize)

1

указатель Пустоты это просто слово размера разыменовываемого указатель, который не подразумевает определенный типа данных. Таким образом, вы не можете делать с ним указательную математику. Чтобы сделать то, что вы пытаетесь сделать, объявите соответствующий указатель в вашей функции, а затем установите его значение, равное значению указателя void параметра.

+0

Что вы имеете в виду под «соответствующим образом напечатанным указателем»? Вы думали о sth как void * tmp = (char *) array + i * objsize для доступа к i-му элементу? – matzui

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