2016-10-23 3 views
0

Я начинаю с C и сталкиваюсь с этой проблемой: я создал функцию, основанную на методе быстрого распределения матриц (Oliveira and Stewart, «Написание научного программного обеспечения», pag 94), и я хочу использовать его для любого типа данных. поэтому я изменил его немного следующим образом:using sizeof (void) внутри malloc

void ** malloc_array2d(size_t m, size_t n){ 

    /* pointer to array of pointers */ 
    void ** pointer; 
    size_t i; 
    /* allocate pointer array of length m */ 
    pointer = malloc(m*sizeof(void)); 
    if(pointer == NULL){ 
    return NULL; 
    } 
    /* allocate storage for m*n entries */ 
    pointer[0] = malloc(m*n*sizeof(void)); 
    if (pointer[0] == NULL) { 
    free(pointer); 
    return NULL; 
    } 
    /* set the pointers */ 
    for (i = 1; i < m; i++) { 
    pointer[i] = pointer[0] + i*n; 
    } 

return pointer; 
} 

, но я получаю ошибку сегментации.

Вопрос: как разрешить выделение памяти для разных типов данных, поскольку sizeof (void) не работает (и действительно, он возвращает только 1)? Любая обратная связь действительно оценена. Спасибо.

+3

Что такое звук одной ладони? Речь идет о том же философском вопросе, что и вопрос о том, какой размер не существует. Вероятно, вы должны выделить некоторое количество * байтов *. –

+3

Вам нужно указать размер файла типа 'malloc_array2d', потому что он не знает, нет ли у вас этого. Вы получите что-то вроде 'void ** malloc_array2d (size_t m, size_t n, size_t element_size);'. –

+0

MSVC говорит о 'sizeof (void)' 'предупреждение C4034: sizeof возвращает 0". Обратите внимание на такие предупреждения. –

ответ

2

void не соответствует типу pointer. pointer ссылки void *, а не void.

Избегайте ошибки в будущем, не кодируя размер ссылочного типа, но кодируя размер указателя с привязкой.

// pointer = malloc(m*sizeof(void)); 
pointer = malloc(sizeof *pointer * m); 

Для следующего выделения, sizeof(void) * m *n является not well defined. Код нуждается в новом подходе.

// pointer[0] = malloc(m*n*sizeof(void)); 

Чтобы выделить различные типы, укажите размер данных.

void ** malloc_array2d(size_t m, size_t n, size_t data_size){ 
    ... 
    unsigned char *p = malloc(data_size * m *n); 
    ... 
    for (i = 0; i < m; i++) { 
    pointer[i] = p + i*n*data_size; 
    } 
+0

это имеет смысл для меня, но если я создаю свой указатель 'void ** внутри функции, как он знает размер? –

+0

@Mattia Paterna Pass в размере данных. – chux

0

Sizeof возвращает количество байтов, которое имеет каждый тип данных. 1 для байта, 2 для int16, 4 для int32 и т. Д. Затем вы можете передать его как параметр с любой проблемой, так как на момент использования функции malloc_2darray вы должны знать конечный тип данных для сопоставления.

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

+0

Что значит« приведение » к окончательному типу данных »? Вы говорите, что он должен вернуть возвращение« malloc »? Потому что это определенно огромный ** НЕТ ** и должен ** не ** быть сделано! – UnholySheep

+0

Хмм, это звучит интересно, так как я думал, сделайте так. Я читал кое-что о **, а не **, чтобы бросить раньше. –

+0

Нет, я имею в виду ** использовать функцию malloc_2darray **, созданную им. Если нет, очень возможно, что программа не знает, как работать с указателями, выделенными с помощью malloc_2darray (ex; char ** p = malloc_2dArray (.., ...); здесь будет присвоено значение ** pa (void **). Что произойдет, если следующие строки будут ** p ++ или похожими? Будет ли он увеличивать байт указателем? Два? Нет инкремента позиции? Лучше всего этого избежать: char ** p = (char **) malloc_2darray (..,. .) – DvTr

-1

Во-первых, значение sizeof (void) всегда равно 1, здесь void означает выделение памяти указателя для нетипизированного типа данных. Я не думаю, что любой другой тип данных занимает гораздо меньше памяти. Ну int, float и т. Д. Потребляет больше бит данных. Если вы хотите, чтобы значение sizeof() возвращало 1, вы можете вручную указать размер в функции malloc() вместо использования функций sizeof() вместе с различными типами данных.

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