2016-01-06 5 views
0

Я новичок в C и StackOverflow.Доступ к значениям указателей в большой массив

Я пытаюсь реализовать решение этого вопроса http://stackoverflow.com/questions/34624027/how-to-create-a-fast-huge-union-array-without-wasting-memory-in-c в Visual Studio-2015. Ниже мой код:

#include "stdafx.h" 

#include "malloc.h" 
#include "inttypes.h" 

#define RESERVED_BYTES 2147483648 

typedef union { 
    void *pv; 
    char *pc; 
    uint8_t *pu8; 
    uint16_t *pu16; 
} parray_type; 

int main() 
{ 
    parray_type parray; 
    parray.pv = calloc(RESERVED_BYTES, 1); 

    // last element in allocated buffer for each type 
    char c = parray.pc[RESERVED_BYTES - 1]; 
    uint8_t u8 = parray.pu8[RESERVED_BYTES - 1]; 
    uint16_t u16 = parray.pu16[RESERVED_BYTES/2 - 1]; 

    // first element in allocated buffer for each type 
    char c_2= parray.pc[0]; 
    uint8_t u8_2 = parray.pu8[0]; 
    uint16_t u16_2 = parray.pu16[0]; 

    printf("c='%c' (%d) u8='0x%x' (%d) u16='%h' (%d)\n", c, c, u8, u8, u16, u16); 
    printf("c='%c' (%d) u8='0x%x' (%d) u16='%h' (%d)\n", c_2, c_2, u8_2, u8_2, u16_2, u16_2); 

    return 0; 
} 

Он компилируется нормально, но когда я пытаюсь запустить его я получаю следующее сообщение об ошибке о назначении char c = parray.pc[RESERVED_BYTES - 1];. Ошибка Unhandled exception at 0x012717F8 in TstLrgArr.exe: 0xC0000005: Access violation reading location 0x7FFFFFFF. Когда я прокомментирую три строки, назначающие c, u8 и u16, я получаю ту же ошибку при присваивании c_2, за исключением того, что нарушение доступа считывает местоположение 0x00000000.

Выходом я думаю ожидал был 2 строкой следующего: c='' (0) u8='0x00' (0) u16='' (0)

Что я сделал не так, или это какое-то ограничение VS-2015?

+0

Я начал с изучения вызова '' calloc() '': его возвращаемого значения и если установлен флаг ошибки (errno и/или GetLastError). Вы пытаетесь выделить 2 Gb сразу - это довольно много. – Tibo

+0

Спасибо за отзыв. Ошибка: «Недостаточно места», поэтому указатель 00000000. Я думал, что точкой решения было то, что он разрешил массивы до 2 Гб. Было ли решение неправильным? –

+0

Единственный (простой) способ получить выделение 2 Гб в Windows - использовать 64-битный. (32-разрядные процессы могут использовать другие функции, чтобы повысить лимит до 3 Гб, но я очень сомневаюсь, что они могут распределить 2 Гб одновременно). Итак: чтобы использовать ответ, на который вы ссылаетесь, скомпилируйте для 64-битного. – Tibo

ответ

0

Максимальный размер, который может выделять calloc, зависит от платформы, на которой вы работаете. Возможно, размер вашего массива может быть большим до #define RESERVED_BYTES 2147483648. calloc, возможно, вернется NULL.

Добавьте NULL-указатель на свой код.

parray.pv = calloc(RESERVED_BYTES, 1); 
if (parray.pv == NULL) 
{ 
    // ... add print error ... 
    return 0; 
} 
+0

Я думал, что calloc (RESERVED_BYTES, 1) инициализирует указатель. ? –

+0

Как я уже отмечал выше, ошибка была «Недостаточно места». В основном я просто скопировал код по этой ссылке: http://stackoverflow.com/questions/34624027/how-to-create-a-fast-huge-union-array-without-wasting-memory-in-c, поэтому я подумал он будет работать нормально. –