Existe um comprimento máximo para uma matriz em C ++?
É um limite de C ++ ou depende da minha máquina? É tweakable? Depende do tipo de matriz é feita?
Posso quebrar esse limite de alguma forma ou tenho que procurar uma maneira melhor de armazenar informações? E qual deve ser a maneira mais simples?
O que tenho que fazer é armazenar int muito longo em uma matriz, estou trabalhando em um ambiente Linux. Minha pergunta é: o que devo fazer se precisar armazenar uma matriz de N inteiros longos com N> 10 dígitos?
Preciso disso porque estou escrevendo algum algoritmo criptográfico (como, por exemplo, o p-Pollard) para a escola, e acertei esse muro de números inteiros e o comprimento da representação de matrizes.
new
oumalloc
. Um pedaço de memória maior que uma matriz pode ser acessado via ponteiro.Ninguém mencionou o limite no tamanho do quadro da pilha .
Existem dois locais em que a memória pode ser alocada:
O limite de tamanho aqui é uma combinação de hardware disponível e da capacidade do sistema operacional para o espaço simular usando outros dispositivos para armazenar temporariamente os dados não utilizados ( ou seja Mover páginas para o disco rígido).
O limite de tamanho aqui é definido pelo compilador (com possíveis limites de hardware). Se você ler a documentação do compilador, poderá ajustar esse tamanho.
Portanto, se você alocar uma matriz dinamicamente (o limite é grande e descrito em detalhes por outras postagens).
Como alternativa, se a matriz estiver alocada na pilha, você estará limitado pelo tamanho do quadro da pilha. Os vetores NB e outros contêineres têm uma pequena presença na pilha, mas geralmente a maior parte dos dados estará no heap.
fonte
new
oumalloc
).Global Arrays
embora não seja uma beleza e seja melhor evitada, elas não se enquadram nas restrições dastack
e você não precisamalloc
/free
trabalha com elas.Analisando isso do ponto de vista prático, e não teórico, em um sistema Windows de 32 bits, a quantidade total máxima de memória disponível para um único processo é de 2 GB. Você pode quebrar o limite acessando um sistema operacional de 64 bits com muito mais memória física, mas fazer isso ou procurar alternativas depende muito dos usuários pretendidos e de seus orçamentos. Você também pode estendê-lo um pouco usando o PAE .
O tipo da matriz é muito importante, pois o alinhamento da estrutura padrão em muitos compiladores é de 8 bytes, o que é muito inútil se o uso da memória for um problema. Se você estiver usando o Visual C ++ para direcionar o Windows, confira a diretiva #pragma pack como uma maneira de superar isso.
Outra coisa a fazer é analisar o que as técnicas de compactação de memória podem ajudá-lo, como matrizes esparsas, compactação instantânea, etc ... Novamente, isso depende muito do aplicativo. Se você editar sua postagem para fornecer mais informações sobre o que realmente está em suas matrizes, poderá obter respostas mais úteis.
Editar: com um pouco mais de informações sobre seus requisitos exatos, seu armazenamento parece estar entre 7,6 GB e 76 GB descompactado, o que exigiria uma caixa de 64 bits bastante cara para armazenar como uma matriz na memória em C ++. Isso levanta a questão de por que você deseja armazenar os dados na memória, onde se presume a velocidade do acesso e permitir o acesso aleatório. A melhor maneira de armazenar esses dados fora de uma matriz é baseada em como você deseja acessá-los. Se você precisar acessar os membros da matriz aleatoriamente, para a maioria dos aplicativos, existem maneiras de agrupar grupos de dados que tendem a ser acessados ao mesmo tempo. Por exemplo, em grandes bancos de dados geográficos e espaciais, os dados geralmente são agrupados por área geográfica. Em termos de programação C ++, você pode substituir o operador da matriz [] para buscar partes de seus dados do armazenamento externo, conforme necessário.
fonte
Concordo com o exposto acima, que se você estiver inicializando sua matriz com
SIZE é limitado pelo tamanho de um número inteiro. Mas você sempre pode localizar um pedaço de memória e apontar para ele, do tamanho que desejar, desde que o malloc não retorne NULL.
fonte
int oops[INT_MAX]{0};
Ele gera,C2148 - total size of array must not exceed 0x7fffffff bytes
66%
memória atualmente usada antes de iniciar meu aplicativo como depuração no Windows 10 com o VS2017, tenho um limite indefinido sobre o tamanho de uma matriz int com a qual posso inicializar0
. Às vezes eu posso fazer isso com ~ 257k elementos, às vezes eu recebo um estouro de pilha. Se eu adicionar algo ao meu aplicativo além do principal e da matriz, esse número será reduzido (obviamente). Eu tive que experimentar para determinar esse número, para não ver como essa métrica pode ser usada além de conhecer seus limites teóricos no vácuo.Para resumir as respostas, estenda-as e responda diretamente à sua pergunta:
Não, o C ++ não impõe limites para as dimensões de uma matriz.
Porém, como a matriz precisa ser armazenada em algum lugar da memória, também se aplicam os limites relacionados à memória impostos por outras partes do sistema do computador. Observe que esses limites não estão diretamente relacionados às dimensões (= número de elementos) da matriz, mas ao tamanho (= quantidade de memória consumida). Dimensões ( D ) e de tamanho de memória ( S ) de uma matriz não é a mesma, como estes são sujeitos a memória ocupada por um único elemento ( E ): S = D * E .
AgoraE depende de:
'espaço desperdiçado' (preenchimento) entre os elementos
Observe também que você geralmente obtém diferentes limitações relacionadas à memória, alocando os dados da matriz na pilha (como uma variável automática:)
int t[N]
ou no heap ( alocação dinâmica commalloc()
/new
ou usando mecanismos STL) ou na parte estática da memória do processo (como uma variável estática:)static int t[N]
. Mesmo ao alocar no heap, você ainda precisa de uma pequena quantidade de memória na pilha para armazenar referências aos blocos de memória alocados ao heap (mas isso geralmente é insignificante).O tamanho do
size_t
tipo não tem influência sobre o programador (presumo que o programador use osize_t
tipo para indexação, como foi projetado para ele), pois o provedor do compilador precisatypedef
dele para um tipo inteiro grande o suficiente para endereçar a quantidade máxima de memória possível para a plataforma fornecida arquitetura.As fontes das limitações de tamanho de memória derivam de
Eles não podem ser 'ajustados' no nível do aplicativo, mas você pode usar um compilador diferente (para alterar os limites de tamanho da pilha), ou portar seu aplicativo para 64 bits, ou para outro sistema operacional ou alterar a configuração física / configuração de memória virtual da máquina (virtual? física?).
Não é incomum (e até aconselhável) tratar todos os fatores acima como distúrbios externos e, portanto, como possíveis fontes de erros de tempo de execução, e verificar cuidadosamente e reagir a erros relacionados à alocação de memória no código do seu programa.
Então, finalmente: enquanto o C ++ não impõe limites, você ainda precisa verificar condições adversas relacionadas à memória ao executar seu código ... :-)
fonte
Como muitas excelentes respostas observadas, existem muitos limites que dependem da sua versão do compilador C ++, sistema operacional e características do computador. No entanto, sugiro o seguinte script no Python que verifica o limite em sua máquina.
Ele usa a pesquisa binária e, em cada iteração, verifica se o tamanho do meio é possível, criando um código que tenta criar uma matriz do tamanho. O script tenta compilá-lo (desculpe, esta parte funciona apenas no Linux) e ajustar a pesquisa binária, dependendo do sucesso. Confira:
Você pode salvá-lo em sua máquina e iniciá-lo, e ele imprimirá o tamanho máximo que você pode criar. Para minha máquina, é 2305843009213693951.
fonte
Acho que uma coisa não foi mencionada nas respostas anteriores.
Estou sempre sentindo um "mau cheiro" no sentido da refatoração quando as pessoas estão usando essas coisas em seu design.
Essa é uma variedade enorme e possivelmente não é a melhor maneira de representar seus dados, tanto do ponto de vista da eficiência quanto do desempenho.
Felicidades,
Roubar
fonte
Se você precisar lidar com dados tão grandes, precisará dividi-los em partes gerenciáveis. Nem tudo se encaixa na memória de qualquer computador pequeno. Provavelmente, você pode carregar uma parte dos dados do disco (o que for razoavelmente adequado), executar seus cálculos e alterações, armazená-los no disco e repetir até concluir.
fonte
Por mais irritantemente inespecíficas que sejam todas as respostas atuais, elas estão certas, mas com muitas ressalvas, nem sempre mencionadas. A essência é que você tem dois limites superiores e apenas um deles é algo realmente definido, então YMMV :
1. Limites de tempo de compilação
Basicamente, o que o seu compilador permitirá. Para o Visual C ++ 2017 em uma caixa x64 do Windows 10, esse é o meu limite máximo em tempo de compilação antes de incorrer no limite de 2 GB,
Se eu fiz isso,
Eu receberia:
Não sei como o 2G se correlaciona com
255999996
/7
. Pesquisei os dois números no Google, e a única coisa que pude achar que estava possivelmente relacionada foi essa * nix Perguntas e Respostas sobre uma problema de precisãodc
. De qualquer maneira, não parece importar qual tipo de matriz int você está tentando preencher, apenas quantos elementos podem ser alocados.2. Limites de tempo de execução
Sua pilha e pilha têm suas próprias limitações. Esses limites são valores que mudam com base nos recursos disponíveis do sistema, além de quão "pesado" é seu próprio aplicativo. Por exemplo, com meus recursos atuais do sistema, posso executar isso:
Mas se eu ajustá-lo um pouco ...
Bam! Estouro de pilha!
E apenas para detalhar todo o peso do ponto do seu aplicativo, foi bom:
Mas isso causou um estouro de pilha:
fonte
Estou surpreso que a função de membro max_size () do std :: vector não tenha sido mencionada aqui.
Sabemos que isso
std::vector
é implementado como uma matriz dinâmica embaixo do capô, portanto,max_size()
devemos fornecer uma aproximação muito próxima do comprimento máximo de uma matriz dinâmica em sua máquina.O programa a seguir cria uma tabela com o comprimento máximo aproximado da matriz para vários tipos de dados.
No meu macOS (clang versão 5.0.1), obtenho o seguinte:
No ideone gcc 8.3 , recebo:
Deve-se notar que esse é um limite teórico e que, na maioria dos computadores, você ficará sem memória muito antes de atingir esse limite. Por exemplo, vemos que para o tipo
char
degcc
, o número máximo de elementos é igual ao máximo destd::size_t
. Tentando isso , obtemos o erro:Por fim, como aponta @MartinYork, para matrizes estáticas, o tamanho máximo é limitado pelo tamanho da sua pilha.
fonte
Como já foi apontado, o tamanho da matriz é limitado pelo seu hardware e seu sistema operacional (man ulimit). Seu software, porém, pode ser limitado apenas por sua criatividade. Por exemplo, você pode armazenar sua "matriz" em disco? Você realmente precisa de longas ints? Você realmente precisa de uma matriz densa? Você precisa mesmo de uma matriz?
Uma solução simples seria usar o Linux de 64 bits. Mesmo que você não possua memória RAM suficiente para o seu array, o sistema operacional permitirá que você aloque memória como se tivesse, uma vez que a memória virtual disponível para o seu processo é provavelmente muito maior que a memória física. Se você realmente precisar acessar tudo na matriz, isso significa armazená-lo no disco. Dependendo dos seus padrões de acesso, pode haver maneiras mais eficientes de fazer isso (por exemplo: usando mmap () ou simplesmente armazenando os dados sequencialmente em um arquivo (nesse caso, o Linux de 32 bits seria suficiente)).
fonte
Eu contornaria isso criando uma matriz dinâmica 2D:
mais sobre isso aqui https://stackoverflow.com/a/936702/3517001
fonte