小談C語言中常見資料類型在32及64位機上的使用(zz)

來源:互聯網
上載者:User

關鍵字: c語言,資料類型,32位,64位

1、概述

  C語言有一些非常基本的資料類型,正是這些基本類型讓我們可以延伸了無限的使用者自訂類型,本文主要介紹了 int, size_t, time_t, long, long long int 等基礎資料型別 (Elementary Data Type)在Linux32 及 Linux64 的使用方式。表面看上去,這些類型確實太基礎太簡單,似乎沒啥可講的,實事似乎也是如此,用過C的對這些都已經非常熟悉了,這還用講?在PC 64位機器 出來之前,我們確實不用太關注這些,因為在32位機上編程,似乎很少出現過什麼問題,但64位機出來了,象Linux 也支援64位機器,問題就來了,為什嗎?因為它們的長度發生了變化,而我們的程式也就有可能需要改變一下。

2、舉例

先舉個例子,如下:

 

C代碼
  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3.  
  4. staticvoid get_length(size_t *size) 
  5.     if (size) 
  6.         *size = 100; 
  7.  
  8. staticvoid test(void) 
  9.     char *buf = strdup("hello world"); 
  10.     int  n; 
  11.  
  12.     printf("buf: %s\n", buf); 
  13.     get_length((size_t*) &n); 
  14.  
  15.     printf("buf: %s, n: %d\n",  buf, n); 
  16.     free(buf); 
  17.  
  18. int main(int argc, char *argv[]) 
  19.     test(); 
  20.     return (0); 
#include <stdio.h>  #include <stdlib.h>    static void get_length(size_t *size)  {      if (size)          *size = 100;  }    static void test(void)  {      char *buf = strdup("hello world");      int  n;        printf("buf: %s\n", buf);      get_length((size_t*) &n);        printf("buf: %s, n: %d\n",  buf, n);      free(buf);  }    int main(int argc, char *argv[])  {      test();      return (0);  }

 

  首先將此程式在32位機的 Linux 上運行一下,如下:

buf: hello world

buf: hello world, n: 100

OK,如我們所料,一切正常。

 

  然後再將些程式在64位機的 Linux 上運行一下,如下:

buf: hello world

buf: (null), n: 100

  奇怪的現象出來了,怎麼printf出的結果為空白呢?暈菜,為啥經過 get_length()/1 後世界改變了,buf 的內容沒有了,被指向一個null 指標,而 buf 明明是還沒有被釋放呀。趕快用 valgrind 檢查一下,

valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out

“2 bytes in 1 blocks are definitely lost in loss record 1 of 1”,說有塊記憶體未被釋放,而在 test() 後面確實釋放過 buf 呀,誰偷偷地給釋放了而沒有告訴俺?更暈菜,難道是 libc 的問題?再用 valgrind 在32位機檢查一下,一切OK,沒有出現64位機上的錯誤提示,說明記憶體確實由 test() 中的 free(buf) 釋放了。

  正當對此問題百思不解時,忽然想到一個問題 int * 至 size_t*  類型轉換會不會有問題?因為 size_t 在32位機上是4位元組,而在64位機上是8位元組,int在32位及64位機上都是4位元組,嗯,問題就在於此,再回頭仔細看看上述代碼,在 test() 中將 &n 由 int * 強制轉換成 size_t *, 這樣可以避免編譯警告,但在 get_length()/1 中呢?它是不會知道 size_t *size 中 size 所指空間是4位元組的,而依然當8位元組對待,這樣在對 *size = 100 進行賦值時就發生了改變,size 所指的8位元組空間發生改變,而實際應該只改變4位元組才是,這便是問題的關鍵所在,所以在遇到此類問題時,一定得要注意基本類型在不同機器上的空間大小了。

 

3、小結

  以上的例子只是一個簡單的例子,也許還容易看得出來,當我們的項目比較大時,這種錯誤可能會偶爾發生一下,那可能就是致命的了,因為有時它並不 會導致程式 異常退出產生core檔案,但卻會改變我們的運行結果,本人就因此問題調試了兩天多的時間才找到原因,另外,即使因此問題產生了 core 檔案,你會發現用 gdb 調試該 core 時根本找不到原因所在。

 

下面列出一些基本類型在32位及64位機上的大小差異

  int long size_t time_t long long int
32位機器 4位元組 4位元組 4位元組 4位元組 8位元組
64位機器 4位元組 8位元組 8位元組 8位元組 8位元組

 

在寫跨平台的程式時,一定要注意這些基本類型的長度大小。

---------------------------------

一、程式運行平台
       不同的平台上對不同資料類型分配的位元組數是不同的。
       個人對平台的理解是CPU+OS+Compiler,是因為:
       1、64位機器也可以裝32位系統(x64裝XP);
       2、32位機器上可以有16/32位的編譯器(XP上有tc是16位的,其他常見的是32位的);
       3、即使是32位的編譯器也可以弄出64位的integer來(int64)。
       以上這些是基於常見的wintel平台,加上我們可能很少機會接觸的其它平台(其它的CPU和OS),所以個人認為所謂平台的概念是三者的組合。
       雖然三者的長度可以不一樣,但顯然相互配合(即長度相等,32位的CPU+32位的OS+32位的Compiler)發揮的能量最大。
       理論上來講 我覺得資料類型的位元組數應該是由CPU決定的,但是實際上主要由編譯器決定(佔多少位由編譯器在編譯期間說了算)。

二、常用資料類型對應位元組數
       可用如sizeof(char),sizeof(char*)等得出

       32位編譯器:

       char :1個位元組
       char*(即指標變數): 4個位元組(32位的定址空間是2^32, 即32個bit,也就是4個位元組。同理64位編譯器)
       short int : 2個位元組
       int: 4個位元組
       unsigned int : 4個位元組
       float: 4個位元組
       double: 8個位元組
       long: 4個位元組
       long long: 8個位元組
       unsigned long: 4個位元組

       64位編譯器:

       char :1個位元組
       char*(即指標變數): 8個位元組
       short int : 2個位元組
       int: 4個位元組
       unsigned int : 4個位元組
       float: 4個位元組
       double: 8個位元組
       long: 8個位元組
       long long: 8個位元組
       unsigned long: 8個位元組

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.