Eu entendo como malloc () funciona. Minha pergunta é, verei coisas assim:
#define A_MEGABYTE (1024 * 1024)
char *some_memory;
size_t size_to_allocate = A_MEGABYTE;
some_memory = (char *)malloc(size_to_allocate);
sprintf(some_memory, "Hello World");
printf("%s\n", some_memory);
free(some_memory);
Omiti a verificação de erros por uma questão de brevidade. Minha pergunta é, você não pode simplesmente fazer o acima, inicializando um ponteiro para algum armazenamento estático na memória? possivelmente:
char *some_memory = "Hello World";
Em que ponto você realmente precisa alocar a memória em vez de declarar / inicializar os valores que você precisa reter?
c
memory
memory-management
randombits
fonte
fonte
malloc()
pode falhar!Respostas:
está criando um ponteiro para uma constante de string. Isso significa que a string "Hello World" estará em algum lugar na parte somente leitura da memória e você terá apenas um ponteiro para ela. Você pode usar a string como somente leitura. Você não pode fazer alterações nele. Exemplo:
Está procurando problemas.
Por outro lado
está alocando uma matriz char (uma variável) e alguns pontos de memória para essa memória alocada. Agora, esse array é tanto de leitura quanto de gravação. Agora você pode fazer:
e o conteúdo do array muda para "hello World"
fonte
const char *s = "hi";
Isso não é realmente exigido pelo padrão?const char const* s;
Para esse exemplo exato, malloc é de pouca utilidade.
O principal motivo pelo qual o malloc é necessário é quando você tem dados que devem ter uma vida útil diferente do escopo do código. Seu código chama malloc em uma rotina, armazena o ponteiro em algum lugar e, eventualmente, chama free em uma rotina diferente.
Um motivo secundário é que C não tem como saber se há espaço suficiente restante na pilha para uma alocação. Se seu código precisa ser 100% robusto, é mais seguro usar malloc porque então seu código pode saber se a alocação falhou e lidar com ela.
fonte
malloc é uma ferramenta maravilhosa para alocar, realocar e liberar memória em tempo de execução, em comparação com declarações estáticas como seu exemplo hello world, que são processadas em tempo de compilação e, portanto, não podem ter seu tamanho alterado.
Malloc é, portanto, sempre útil quando você lida com dados de tamanho arbitrário, como ler o conteúdo do arquivo ou lidar com sockets, e você não está ciente do comprimento dos dados a processar.
Claro, em um exemplo trivial como o que você deu, malloc não é a mágica "ferramenta certa para o trabalho certo", mas para casos mais complexos (criando uma matriz de tamanho arbitrário em tempo de execução, por exemplo), é a única maneira de ir.
fonte
Se você não sabe o tamanho exato da memória que precisa usar, você precisa de alocação dinâmica (
malloc
). Um exemplo pode ser quando um usuário abre um arquivo em seu aplicativo. Você vai precisar ler o conteúdo do arquivo na memória, mas é claro que você não sabe o tamanho do arquivo com antecedência, já que o usuário seleciona o arquivo no local, em tempo de execução. Então, basicamente, você precisamalloc
quando não sabe o tamanho dos dados com os quais está trabalhando com antecedência. Pelo menos esse é um dos principais motivos de usomalloc
. Em seu exemplo com uma string simples que você já sabe o tamanho em tempo de compilação (mais você não quer modificá-la), não faz muito sentido alocá-la dinamicamente.Um pouco fora do assunto, mas ... você tem que ter muito cuidado para não criar vazamentos de memória ao usar
malloc
. Considere este código:Você vê o que há de errado com este código? Há uma declaração de retorno condicional entre
malloc
efree
. Pode parecer bom no início, mas pense nisso. Se houver um erro, você retornará sem liberar a memória alocada. Esta é uma fonte comum de vazamentos de memória.É claro que este é um exemplo muito simples e é muito fácil ver o erro aqui, mas imagine centenas de linhas de código repletas de ponteiros,
malloc
s,free
s e todos os tipos de tratamento de erros. As coisas podem ficar complicadas muito rápido. Esta é uma das razões pelas quais prefiro C ++ moderno em vez de C em casos aplicáveis, mas esse é um outro tópico.Portanto, sempre que usar
malloc
, certifique-se de que sua memória seja o mais provávelfree
possível.fonte
é ilegal, os literais de string são
const
.Isso alocará uma matriz de caracteres de 12 bytes na pilha ou globalmente (dependendo de onde for declarado).
Se você quiser deixar espaço para outras manipulações, pode especificar que o tamanho da matriz seja maior. (Porém, não coloque 1 MB na pilha.)
fonte
Uma razão pela qual é necessário alocar a memória é se você deseja modificá-la em tempo de execução. Nesse caso, um malloc ou um buffer na pilha pode ser usado. O exemplo simples de atribuição de "Hello World" a um ponteiro define a memória que "normalmente" não pode ser modificada em tempo de execução.
fonte