Por que precisamos de elenco que retorna malloc?
Pergunta
int length = strlen(src);
char *structSpace = malloc(sizeof(String) + length + 1);
String *string = (String*) structSpace;
int *string = (int*) structSpace;
* Eu criei uma estrutura chamada de Cordas
Solução
Você não. void*
vai implicitamente convertido para o que você precisa em C. Veja também C FAQ sobre o porquê você iria querer evitar explicitamente lançando o retorno de malloc em C. @ resposta de Sinan ilustra ainda mais porque este tem sido seguido de forma inconsistente.
Outras dicas
Porque malloc retorna um ponteiro para nulo, ou seja, é simplesmente alocar blocos de memória sem ter em conta quanto aos dados que serão armazenados lá. Em C ++ seu * vazio retornado não será implicitamente convertido para o ponteiro de seu tipo. No seu exemplo, você não lançaram o malloc voltou. Malloc voltou a * vazio que foi implicitamente convertido para um char *, mas na próxima linha você ... ok, isso não faz muito sentido.
A lista C FAQ é um recurso inestimável: Por que algum código lançar cuidadosamente os valores devolvidos pela malloc para o tipo de ponteiro sendo alocados? .
Esta é uma das poucas questões que faz a declaração "C ++ é um super conjunto de C" não é completamente verdade. Em C, um ponteiro void
pode ser implicitamente convertido para qualquer outro tipo de ponteiro. No entanto, C ++ é um pouco mais rigoroso com a segurança de tipos, então você precisa converter explicitamente o valor de retorno de malloc
para o tipo apropriado. Normalmente, isso não é um grande problema, porque o código C ++ tende a new
uso ao invés de malloc
, que não requer typecasting.
Em C, lançando o resultado de malloc é desnecessária e não deve ser feito. Se o fizer, pode, por exemplo, encobrir o erro de não ter #include <stdlib.h>
, então você não tem um protótipo para malloc no espaço. Este, por sua vez, pode levar a outros erros e falta de portabilidade (embora os piores criminosos a esse respeito são agora quase obsoleto).
Em C ++, você deve converter o resultado de malloc para atribuí-la a um ponteiro para qualquer tipo diferente de vazio. A menos que você realmente necessidade para escrever código que pode ser compilado como C ou C ++, no entanto, geralmente você deve evitar o uso de malloc
em C ++ em tudo e alocar memória usando new
.
Você tende a ver este tipo de código C a partir de novatos (ou ++ programadores C :-)):
int main() {
int len = 40;
char *my_string = (char *) malloc(sizeof(char)*len);
return 0;
}
Esta é desnecessário e mal, você pode evitar o elenco inútil via incluindo stdlib.h
#include <stdlib.h>
int main() {
int len = 40;
char *my_string = malloc(sizeof(char)*len);
return 0;
}
Você deve considerar fortemente lançando depois de usar o comando malloc porque prevê uma maior portabilidade e maior compatibilidade com outras partes do seu programa. Se você não fizer isso, você pode correr o risco de tipos de dados incompatíveis que podem resultar em erros.