Como retornar o tamanho total de um buffer em C++

Então, o que eu tenho feito é utilizar o sizeof(buffer) porém ele retorna o valor do tamanho do tipo e não da contagem de todos os elementos :confused:

float *buffer = NULL;
*buffer = new float[16];

int buffer_size = sizeof(*buffer); //Retorna "8", mas não deveria retornar "16*8"?

Então o que eu tenho feito é multiplicar o ‘size’ do buffer pelo sizeof do tipo, porém se só metade desse buffer estiver com dados isso não vai ser preciso o suficiente, alguma dica?

Quando se usa arrays comuns não tem outro jeito, vc vai ter que arrumar uma forma “manual” de gerenciar a capacidade total e a quantidade de dados atual do buffer.

const unsigned SIZE = 16;
unsigned length = 0;
float *buffer = new float[SIZE];
if ( length < SIZE ) buffer[length++] = 1.0;
if ( length < SIZE ) buffer[length++] = 2.0;
if ( length < SIZE ) buffer[length++] = 3.0;

Pra facilitar, crie uma struct contendo todos os dados que precisa e funções para manipulá-la.

struct Buffer {
  unsigned size;
  unsigned length;
  float *data;
};

Buffer* buffer_create(unsigned size) {
  Buffer *buffer = new Buffer();
  buffer->size = size;
  buffer->length = 0;
  buffer->data = new float[size];
  return buffer;
}

void buffer_insert(Buffer *buffer, float number) {
  if (buffer->length < buffer->size)
    buffer->data[buffer->length++] = number;
}

O código acima pode conter erros, mas ele foi pensado apenas para dar uma idéia do que pode ser feito.

Claro que, já que está usando C++, implementar uma solução genérica e orientada à objetos seria mais adequada, segura e elegante.

Mas antes de tentar reinventar a roda, veja se alguma coisa da biblioteca padrão não te ajuda. Por exemplo, o std::vector pode ser demais para o que vc precisa, contudo, a std::array poderia se encaixar perfeitamente à sua necessidade.

Qualquer coisa, conte mais sobre seu problema e o contexto em que vc quer usar isso.

1 curtida

Consegui pegar a ideia! Muito obrigado :D. Estou fazendo um alocador de dados pra ser usado com a JNI do Java. Já que tudo que é alocado no java inclusive do java.nio é tudo alocado na JVM :confused:

Então eu to fazendo tudo com métodos nativos e alocando na Heap pra acesso mais rápido, pq ficar tacando dados enormes na Stack é inviável (até porque a stack é 64kb :confused:) .

Reli sua resposta e acho que entendi melhor o que vc pretende fazer através do JNI.

Contudo, se sua única preocupação for com a JVM alocando coisas na Stack ao invés de na Heap como vc explica neste trecho:

Acredito que vc pode ficar tranquilo com relação a isso e focar em outros aspectos do seu projeto, pois embora o consumo de memória da JVM seja grande, ela sabe gerenciar a memória que aloca.

Vc tá fazendo isso apenas para aprendizado? Se não, poderia compartilhar mais detalhes sobre seu plano e como pretende fazer um trabalho melhor que o que a JVM já faz?

1 curtida

Eu sou um Game Developer então visto que a stack suporta somente 64kb, veja a IMPOSSIBILIDADE de por exemplo carregar um modelo 3D de 7MB por exemplo.

O OpenGL se comunica somente utilizando Buffers, é da especificação dele, não existe saida, use buffers ou nao use OpenGL.

Sendo assim, é impossível trabalhar com game dev no java sem alocar conteudo na Heap.

Certo. Agora algumas considerações:

Os ponteiros C/C++ (que atuam como buffers) tem um endereço qualquer.
Structs C/C++ podem, se feita a implementação JNI correta, ser “convertidas” em classes Java.

A classe Java, para um FloatBuffer por exemplo, teria basicamente 2 campos: um int que guarda o endereço de memoria, visto que um endereço de memoria é um hexadecimal ele pode ser convertido para decimal facilmente e uma float array.

Uma outra classe poderia ter metodos para alocação e desalocação da memoria utilizando metodos nativos.

Quando no Java eu chamasse MintFloatBuffer mfb = BufferAllocator.mallocFloat(16) ele criasse na heap um buffer “cheio” de zeros e retornasse o endereço da memoria desse buffer e sua float array vazia e utilizando outros metodos metodos nativos para preencher os campos do buffer.

Com isso seria possivel alocar grandes dados de arquivos de forma bem mais rapida que ficar quebrando o arquivo e passando partes deles (coisa aliais impossivel no OpenGL vc precisa de TODOS os dados completos duma vez).

Entendi. Acabei ignorando o fato de que quer usar libs nativas.

Você conhece a LWJGL? Ela faz esta ponte que você precisa pra trabalhar com OpenGL (e outras libs) através de Java.

Ela é a base do LibGDX, que é um game framework e pra game engine JMonkey, além de outras coisas.

Acredito que valha a pena olhar.

1 curtida