Qual é a diferença entre size_t e int em C ++?
Pergunta
Em vários exemplos C ++ eu vejo um uso do size_t tipo onde eu teria usado um simples int. Qual é a diferença, e por que size_t deve ser melhor?
Solução
A partir o amistoso Wikipedia :
Os arquivos Stdlib.h e cabeçalho stddef.h definir um tipo de dados chamado size_t que é usado para representar o tamanho de um objeto. funções de biblioteca que levam tamanhos esperar que eles sejam do tipo size_t, e os avalia operador sizeof para size_t.
O tipo real de size_t é dependente de plataforma; um erro comum é assumir size_t é o mesmo que int não assinado, que pode levar a erros de programação, particularmente como arquiteturas de 64 bits se tornam mais prevalentes.
Além disso, verifique Por size_t importa
Outras dicas
size_t é o tipo usado para representar tamanhos (tal como o nome indica). Sua plataforma (e até mesmo potencialmente implementação) dependente, e deve ser usado apenas para esse fim. Obviamente, o que representa um tamanho, size_t é não assinado. Muitas funções stdlib, incluindo malloc, sizeof e várias funções de operação corda usar size_t como um tipo de dados.
Um int é assinado por padrão, e apesar de seu tamanho também é dependente de plataforma, que será um 32bits fixos na maioria máquina moderna (e que size_t é de 64 bits em 64-bits arquitetura, int permanecem 32bits longa sobre essas arquiteturas ).
Para resumir:. Uso size_t para representar o tamanho de um objeto e int (ou longo) em outros casos
É porque size_t pode ser outra coisa senão um int (talvez um struct). A idéia é que ele separa-lo do trabalho do tipo subjacente.
O tipo size_t
é definido como o tipo integral sem sinal do operador sizeof
. No mundo real, você vai ver muitas vezes int
definida como 32 bits (para compatibilidade com versões anteriores), mas size_t
definida como 64 bits (assim você pode declarar matrizes e estruturas de mais de 4 GiB de tamanho) em plataformas de 64 bits. Se um long int
é também de 64-bits, isto é chamado a convenção LP64; se long int
é de 32 bits, mas long long int
e ponteiros são 64 bits, que é LLP64. Você também pode obter o inverso, um programa que instruções usos de 64 bits para a velocidade, mas ponteiros de 32 bits para poupar memória. Além disso, int
é assinado e size_t
não está assinado.
Houve historicamente uma série de outras plataformas onde os endereços eram mais largo ou mais curto do que o tamanho natural de int
. De fato, nos anos 70 e início dos anos 80, este era mais comum do que não: todos os microcomputadores de 8 bits populares tiveram registros de 8 bits e endereços de 16 bits, e a transição entre 16 e 32 bits também produziu muitas máquinas que tinha endereços mais amplo do que seus registos. Eu ocasionalmente ainda ver perguntas aqui sobre Turbo C para MS-DOS, cujo modo de memória enorme tinha endereços de 20 bits armazenados em 32 bits em uma CPU de 16 bits (mas que poderia apoiar o conjunto de instruções de 32 bits do 80386); o Motorola 68000 teve uma ALU de 16 bits com registros de 32 bits e endereços; havia minicomputadores IBM com, endereços de 24 bits ou de 31 bits 15 bits. Você também ainda ver diferentes tamanhos ALU e endereço-ônibus em sistemas embarcados.
Toda vez int
é menor do que size_t
, e você tentar armazenar o tamanho ou o deslocamento de um grande arquivo ou objeto em um unsigned int
, existe a possibilidade de que ele poderia transbordar e causar um erro. Com uma int
, há também a possibilidade de obter um número negativo. Se um int
ou unsigned int
é mais amplo, o programa será executado corretamente, mas perder a memória.
Geralmente, você deve usar o tipo correto para a finalidade, se você quer portabilidade. Muitas pessoas irá recomendar que você usar a matemática assinado em vez de sem assinatura (para evitar desagradáveis, erros sutis como 1U < -3
). Para o efeito, os define biblioteca padrão ptrdiff_t
em <stddef.h>
como o tipo assinada do resultado da subtração um ponteiro de outro.
Dito isso, uma solução poderia ser a de limites a verificar todos os endereços de e deslocamentos contra INT_MAX
e quer 0
ou INT_MIN
conforme apropriado, e ligue os avisos do compilador sobre a comparação assinado e quantidades não assinados no caso de você perder qualquer. Você deve sempre, sempre, sempre estar verificando seus acessos de matriz para estouro em C de qualquer maneira.
A definição de SIZE_T
é encontrada em:
https://msdn.microsoft.com/en-us/library/cc441980. aspx e https://msdn.microsoft.com/en- us / library / cc230394.aspx
Colar aqui as informações necessárias:
SIZE_T
é um ULONG_PTR
que representa o número máximo de bytes para o qual um ponteiro pode apontar.
Este tipo é declarado o seguinte:
typedef ULONG_PTR SIZE_T;
A ULONG_PTR
é um tipo longo não assinado usado para a precisão do ponteiro. É usado quando lançando um ponteiro para um tipo longo para executar a aritmética de ponteiro.
Este tipo é declarado o seguinte:
typedef unsigned __int3264 ULONG_PTR;