Saturday, May 2, 2015

Khi khai báo một struct thì nó sẽ được cấp phát tự động một vùng nhớ có độ dài mà coder khó có thể biết chính xác. Ở phần lớn các bài toán coder không cần quan tâm xem struct mà mình khai báo sẽ được cấp phát như thế nào và nó được cấp vùng nhớ bao nhiêu byte, tuy nhiên ở một vài bài toán đặc thù thì coder phải kiểm soát, biết chắc chắn struct mà mình khai báo sẽ được cấp phát như thế nào, khi đó coder được cung cấp các thuộc tính để thêm vào struct để làm việc đó.

1. __attribute__ aligned 
Trong bài toán liên quan đến các protocol khi mà định dạng gói tin được chỉ rõ: có bao nhiêu field, độ dài các field là bao nhiêu, ... Vì vậy để chương trình có thể chạy đúng protocol thì khi coder khai báo struct để biểu diễn các field đó phải làm sao đó để chắc chắn struct mà mình khai báo sẽ có độ dài đúng bằng độ dài mà protocol đó định nghĩa.

Khai báo:

struct Aligned_t  
 {  
      char cdata;  
      int idata;  
      float fdata;  
 }__attribute__ ((aligned (8)));

Thuộc tính aligned(n) dùng để cho biết struct sẽ được cấp vùng nhớ có độ dài
sizeof struct = n*x, trong đó n là số byte để aligne, giá trị n = 2^m, tức là bằng cấp số mũ của 2; x là số nguyên dương với điều kiện x >= 1. Ví dụ trên n = 8, vì vậy biến kiểu struct Aligned_t sẽ được cấp vùng nhớ có độ dài là cấp số nhân của 8.

2. __attribute__((packed))
Dùng để minimum độ dài vùng nhớ của struct, mục đích tiết kiệm bộ nhớ.
Khai báo:
 struct Packed_t  
 {  
      char cdata; //1  
      int idata; //4  
      float fdata; //4  
 }__attribute__((packed));// == minimum ==> 9  
   

Ex
attribute.c
 #include <stdio.h>  
   
   
 struct Normal_t  
 {  
      char cdata; //4  
      int idata; //4  
      float fdata; //4  
 };// 12  
   
 struct Aligned_t  
 {  
      char cdata;  
      int idata;  
      float fdata;  
 }__attribute__ ((aligned (8))); // 12 == align 8 ==> 16  
   
 struct Packed_t  
 {  
      char cdata; //1  
      int idata; //4  
      float fdata; //4  
 }__attribute__((packed));// == minimum ==> 9  
   
    
 int main(int argc, char **argv)  
 {  
      printf("sizeof(char): %d\n", (int)sizeof(char));  
      printf("sizeof(int): %d\n", (int)sizeof(int));  
      printf("sizeof(float): %d\n", (int)sizeof(float));  
      printf("sizeof(long): %d\n", (int)sizeof(long));  
      printf("\n\n");  
   
      struct Normal_t m1;  
      struct Aligned_t m2;  
      struct Packed_t m3;  
   
      printf("sizeof(Normal_t): %d\n", (int)sizeof(m1));  
      printf("sizeof(Aligned_t): %d\n", (int)sizeof(m2));  
      printf("sizeof(Packed_t): %d\n", (int)sizeof(m3));  
   
      return 0;  
 }       
   

Compile & Execute
 $ gcc attribute.c   
 $ ./a.out   
 sizeof(char): 1  
 sizeof(int): 4  
 sizeof(float): 4  
 sizeof(long): 8  
   
   
 sizeof(Normal_t): 12  
 sizeof(Aligned_t): 16  
 sizeof(Packed_t): 9  
   


Xem thêm Specifying Attributes of Types

Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Lập trình hệ thống nhúng Linux . Powered by Luong Duy Ninh -