Um aplicativo de teste simples:
cout << new int[0] << endl;
saídas:
0x876c0b8
Então parece que funciona. O que o padrão diz sobre isso? É sempre legal "alocar" um bloco vazio de memória?
Um aplicativo de teste simples:
cout << new int[0] << endl;
saídas:
0x876c0b8
Então parece que funciona. O que o padrão diz sobre isso? É sempre legal "alocar" um bloco vazio de memória?
Respostas:
A partir de 5.3.4 / 7
From 3.7.3.1/2
Além disso
Isso significa que você pode fazê-lo, mas não pode legalmente (de uma maneira bem definida em todas as plataformas) desreferenciar a memória que obtém - você só pode transmiti-la para excluir a matriz - e deve excluí-la.
Aqui está uma nota de rodapé interessante (isto é, não uma parte normativa do padrão, mas incluída para fins de exposição) anexada à frase de 3.7.3.1/2
fonte
new[]
com umdelete[]
- qualquer que seja o tamanho. Em particular, quando você chamarnew[i]
você precisa de um pouco mais de memória do que o que você está tentando alloc, a fim de armazenar o tamanho da matriz (que é usado mais tarde pordelete[]
quando desalocá)Sim, é legal alocar uma matriz de tamanho zero como esta. Mas você também deve excluí-lo.
fonte
int ar[0];
é ilegal, por que tudo bem?sizeof (type)
é esperado que nunca retorne zero. Veja por exemplo: stackoverflow.com/questions/2632021/can-sizeof-return-0-zeroTodo objeto tem uma identidade única, ou seja, um endereço exclusivo, o que implica um comprimento diferente de zero (a quantidade real de memória será aumentada silenciosamente, se você solicitar zero bytes).
Se você alocasse mais de um desses objetos, descobriria que eles têm endereços diferentes.
fonte
operator []
também armazena o tamanho da matriz em algum lugar (consulte isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array ). Portanto, se a implementação alocar a contagem de bytes com os dados, ela poderá alocar a contagem de bytes e 0 bytes para os dados, retornando o ponteiro 1-passado-último.operator new[]
devem retornar indicadores diferentes. Entre,new expression
há algumas regras adicionais (5.3.4). Não consegui encontrar nenhuma pista de que,new
com tamanho 0, seja realmente necessário para alocar qualquer coisa. Desculpe, diminuí a votação porque acho que sua resposta não está respondendo às perguntas, mas está fornecendo algumas declarações controversas.new[]
implementação para retornar endereços em uma faixa onde não há memória dinâmica mapeada, portanto, não realmente usando qualquer memória (ao usar espaço de endereço)while(!exitRequested) { char *p = new char[0]; delete [] p; }
loop sem reciclar ponteiros entraria em pó antes que pudesse ficar sem espaço de endereço, mas em uma plataforma com ponteiros de 32 bits, seria suposição muito menos razoável.Sim, é totalmente legal alocar um
0
bloco de tamanhonew
. Você simplesmente não pode fazer nada útil com ele, pois não há dados válidos para você acessar.int[0] = 5;
é ilegal.No entanto, acredito que o padrão permite coisas como
malloc(0)
retornarNULL
.Você ainda precisará de
delete []
qualquer ponteiro que voltar da alocação.fonte
Eu encontrei o Effective C ++ Third Edition dito assim no "Item 51: Aderir à convenção ao escrever novo e excluir".
fonte
Eu garanto a você que o novo int [0] lhe custa espaço extra desde que eu o testei.
Por exemplo, o uso de memória de
é significativamente menor que
O uso de memória do segundo trecho de código menos o do primeiro trecho de código é a memória usada para os numerosos novos int [0].
fonte