Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

178
Views
Alineación malloc y C: ¿es segura esta optimización hecha a mano?

Puse todo el código pero, por supuesto, está en archivos diferentes (archivos .h y .c )

 typedef unsigned char ubyte; typedef unsigned int uint; #include<stdbool.h> typedef struct Cube { ubyte n; ubyte e; ubyte s; ubyte w; } Cube; typedef struct Piece { Cube c; bool is_main; char offset_n; char offset_s; } Piece; typedef struct Block { ubyte total; Piece* pieces; } Block; Block *block_create(uint nb_pieces) { Block *block = malloc(sizeof(Block) + (sizeof(Piece) * nb_pieces)); block->pieces = (Piece *) (&block + sizeof(Block)); return block; }

Me pregunto si esta línea de código: block->pieces = (&block + sizeof(Block)); estará siempre a salvo. Quiero decir: ¿podemos estar seguros de que, inmediatamente después de sizeof(Piece) , tendremos precisamente (sizeof(Piece) * nb_pieces) ? ¿Estamos seguros de que nunca habrá un problema de alineación (es decir, tal vez si está alineado en 64 bits, la memoria para sizeof(Block) será inferior a 8 bytes y block->pieces no debería apuntar exactamente a sizeof(Block) , pero " sizeof(Block) 64 bits alineados").

Espero ser lo suficientemente claro.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Primero, esto no está haciendo lo que esperas, y por múltiples razones:

 block->pieces = (&block + sizeof(Block));

Primero, &block es la dirección de la variable block , no el contenido de block , y tiene el tipo block ** . A lo sumo, puede agregar con seguridad 1 valor de este puntero porque cualquier otra cosa creará un puntero más allá del final de esta variable que no es válido.

Entonces necesitarías cambiar &block a block . Eso aún no hará lo que espera porque la aritmética de punteros incrementa la dirección sin procesar en múltiplos del tamaño del objeto. Por lo tanto, agregar sizeof(Block) a esto no es mover hacia arriba 1 elemento de la matriz, sino mover hacia arriba los elementos de la matriz sizeof(Block) .

Para solucionar esto, necesitaría block + 1 . Ahora debe comenzar a preocuparse por la alineación. Para que su matriz de Pieces se alinee correctamente, debe verificar si _Alignof(Block) y _Alignof(Piece) son iguales. De lo contrario, deberá agregar bytes de relleno:

 int padding = 0; if (_Alignof(Block) % _Alignof(Piece) != 0) { padding = _Alignof(Piece) - (_Alignof(Block) % _Alignof(Piece)); } Block *block = malloc(sizeof(Block) + padding + (sizeof(Piece) * nb_pieces)); block->pieces = (Piece *)((char *)(block + 1) + padding);

Por supuesto, puede evitar todo esto haciendo que el miembro de pieces sea un miembro de matriz flexible :

 typedef struct Block { ubyte total; Piece pieces[]; } Block;

Y la asignación por sí sola será suficiente.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!