É necessário multiplicar por sizeof (char) ao manipular memória?
-
06-07-2019 - |
Pergunta
Ao usar malloc e fazer manipulação de memória semelhante posso contar com sizeof (char) sendo sempre 1?
Por exemplo, eu preciso alocar memória para N elementos do tipo char
. É multiplicar por sizeof( char )
necessário:
char* buffer = malloc( N * sizeof( char ) );
ou posso contar com sizeof (char) sempre sendo 1 e simplesmente ignorar a multiplicação
char* buffer = malloc( N );
Eu entendo completamente que sizeof
é avaliado durante a compilação e, em seguida, o compilador pode até compilar a multiplicação e assim a penalidade de desempenho será mínima e muito provavelmente zero.
Estou perguntando principalmente sobre a clareza de código e portabilidade. É este multiplicação nunca necessário para o tipo char
?
Solução
Enquanto não for necessário, eu considero boa prática licença no sizeof (char) porque torna o código mais legível e evita o uso de um número mágico. Além disso, se as necessidades de código a ser alterado mais tarde para que em vez de um caractere é mallocing o tamanho de algo em um ponteiro para esse objeto, é mais fácil para alterar o código que se você tiver apenas um "1".
Outras dicas
Por definição, sizeof (char) é sempre igual a 1. Um byte é o tamanho do personagem em C, qualquer que seja o número de bits em um byte existe (8 na CPU de desktop comum).
O exemplo típico em que um byte é não 8 bits é o PDP-10 e outra velha, mini-computador-como arquiteturas com 9/36 bits de bytes. Mas bytes que não são 2 ^ N estão se tornando extremamente incomum Acredito
Além disso, eu acho que isso é melhor estilo:
char* buf1;
double* buf2;
buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);
porque funciona independentemente do tipo ponteiro é.
sizeof(char)
é sempre 1, não importa que tipo de manipulação de memória que você faz.
No entanto, sizeof(TCHAR)
pode variar dependendo de suas opções de compilação.
Eu considero uma espécie de anti-padrão . É sinal de que o programador não sabia bem o que ele / ela estava fazendo, o que lança imediatamente o resto do código na luz duvidosa.
Com certeza, não é (citando Wikipedia) "ineficaz", mas eu encontrá-lo "longe de ser ideal". Não custa nada em tempo de execução, mas enche o código de lixo desnecessário, o tempo todo sinalizando que alguém pensou que necessário.
Além disso, observe que a expressão não analisa como uma função de chamada: sizeof
não é uma função. Você não está chamando uma função passando o símbolo mágico char
. Você está aplicando o built-in unário sizeof
operador de prefixo para uma expressão, e sua expressão é, neste caso, um elenco à char
tipo, que em C é escrito como (char)
.
É perfeitamente possível, e altamente recomendado sempre que possível, usar sizeof
em outras expressões, ele irá produzir o tamanho do valor da expressão:
char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);
Isto irá imprimir 1
, sempre, em todas as implementações conformes C.
Eu também concordo fortemente com David Cournapeau e considerar a repetição do tipo nome em uma malloc()
-chamada para também ser uma espécie de anti-padrão.
Em vez de
char *str;
str = malloc(N * sizeof (char));
que muitos iria escrever para alocar um buffer de cadeia N-character-capacidade, eu iria com
char *str;
str = malloc(N * sizeof *str);
Ou (para cordas apenas) omitir o sizeof
conforme acima, mas isso, claro, é mais geral e funciona tão bem para qualquer tipo de ponteiro.
Não é necessário. Consulte aqui (por exemplo).
sizeof(char)
sizeof
retorna um número de bytes o número de bits por byte é irrelevante (e em termos práticos, é de qualquer maneira 8).
Outra coisa a ter em mente é que o compilador estaticamente sabe o valor de sizeof (char) é 1 e ele também sabe que multiplicar um número por uma estática 1 implica a multiplicação não precisa ser feito; o compilador irá otimizá-lo para fora. Preocupações de desempenho não deve entrar em consideração por estes motivos.
De "padrão New C. Um comentário econômico e cultural".
- Estatísticas: 2,0% do sizeof são tomadas a partir
char
e 1,5% - deunsigned char
. Página 1033 em 1,2 versão do livro. - página 1037.
O número de bits na representação de um tipo de personagem é irrelevante. Por definição o número de bytes no byte um tipo de caracteres é um.
Coding Guidelines Developers vezes associar um byte como sempre contendo oito bits. Em hosts onde o tipo de caractere é de 16 bits, isso pode levar à suposição de que incorrecta aplicar sizeof a um tipo de personagem irá retornar o valor 2. Estas questões são discutidas em outro lugar.
Usando o sizeof (char) torna seu código mais legível e portátil.
Em x86, todos nós sabemos que um personagem é 1 byte. Mas explicitamente escrevê-la ajuda a tornar suas intenções mais clara, que é sempre uma coisa boa.
Além disso, se o seu código é colocado em alguma outra plataforma, onde um personagem não é 1 byte. E se um personagem era apenas 4 bits em vez disso?
Acordado, não é necessário, mas não retardar seu tempo de execução para baixo e ele vai pagar nesse caso raro que você precisa para portar seu código para uma arquitetura diferente.