`
zsxxsz
  • 浏览: 451114 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

小谈C语言中常见数据类型在32及64位机上的使用

阅读更多

1、概述

  C语言有一些非常基本的数据类型,正是这些基本类型让我们可以延伸了无限的用户自定义类型,本文主要介绍了 int, size_t, time_t, long, long long int 等基本数据类型在Linux32 及 Linux64 的使用情况。表面看上去,这些类型确实太基础太简单,似乎没啥可讲的,实事似乎也是如此,用过C的对这些都已经非常熟悉了,这还用讲?在PC 64位机器出来之前,我们确实不用太关注这些,因为在32位机上编程,似乎很少出现过什么问题,但64位机出来了,象Linux 也支持64位机器,问题就来了,为什么?因为它们的长度发生了变化,而我们的程序也就有可能需要改变一下。

2、举例

先举个例子,如下:

 

#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 的内容没有了,被指向一个空指针,而 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字节

 

在写跨平台的程序时,一定要注意这些基本类型的长度大小。

 

个人微博:http://weibo.com/zsxxsz

 

2
0
分享到:
评论
1 楼 sunzihao128858 2014-09-26  
老大的,呵呵。再读一遍。

相关推荐

    C语言常见问题及面试集

    ##### 1.2 64位机上的64位类型是什么样的? 在64位机器上,`long long`类型通常用于表示64位整数。这意味着`long long`类型的变量可以存储从-9,223,372,036,854,775,808到9,223,372,036,854,775,807之间的整数...

    C语言在凌阳十六位单片机中的应用

    C语言提供了变量、数据类型、运算符、控制结构(如if-else、switch-case、for、while循环)等基本元素,这些在凌阳单片机编程中同样适用。在凌阳单片机上,C语言编写的代码需要经过编译器转换成机器指令,因此,了解...

    C语言常见面试题大全

    在C语言中,`switch`语句的参数不能是浮点型或任何其他非整型数据类型,因为其设计初衷是为了进行整数值的快速比较。 #### 8. 判断是否为2的幂 给定的代码片段通过位运算判断一个数是否为2的幂。具体来说,如果一...

    495个C语言常见问题集

    #### 1.2 64位机上的64位类型是什么样的? 在64位机器上,`long int`和`long long int`类型通常被定义为64位。这意味着它们可以存储从-9,223,372,036,854,775,808到9,223,372,036,854,775,807之间的整数(对于`long...

    常见C语言笔试题

    在16位PC机上,通常`char`占用1字节,`int`占用2字节,`long int`占用4字节,`float`占用4字节,`double`占用8字节。 #### 7. 表达式的值 - **知识点**:复合表达式的计算结果。 - **选项分析**: - A) 错误。...

    C语言—— 数据类型运算符与表达式PPT学习教案.pptx

    每种数据类型的大小和取值范围因硬件平台而异,但在IBM PC机上,例如,int通常占16位,取值范围是-32768到32767;char占8位,取值范围是-128到127;float占32位,大约能表示3.4e-38到3.4e38之间的数;double占64位,...

    C语言常见问题及规避和解决办法

    ### C语言常见问题及规避和解决办法 #### 1. 声明和初始化 **1.1 如何决定使用哪种整数类型?** 在C语言中,选择正确的整数类型非常重要,因为不同的类型有不同的存储空间和范围。例如,`short int`、`int` 和 `...

    C语言常见问题集[CCFAQ V0.9.4]

    2. **64位机上的64位类型是什么样的?** - 在64位系统上,`long long`通常被用来表示64位整数。这种类型的大小为8字节(64位)。 - `int`和`long`在某些64位系统上可能也是64位宽,但这不是标准规定的,具体取决于...

    C语言FAQ 常见问题列表

    o 2.2 64 位机上的 64 位类型是什么样的? o 2.3 怎样定义和声明全局变量和函数最好? o 2.4 extern 在函数声明中是什么意思? o 2.5 关键字 auto 到底有什么用途? o 2.6 我似乎不能成功定义一个链表。我试过 ...

    C语言单片机 C语言单片机 单片机 C语言单片机

    C语言在单片机上的应用,主要是通过编写源代码来控制这些硬件资源。 C语言在单片机编程中的主要知识点包括: 1. 数据类型:C语言提供了多种数据类型,如int、char、float等,用于存储不同类型的数值或字符。在...

    单片机C语言编程的常见问题与分析.pdf

    单片机C语言编程是一种在单片机上应用广泛且高效的编程语言,其开发过程中的常见问题一直是硬件开发者关心的焦点。本文将详细探讨单片机C语言编程中经常遇到的问题,并分析这些问题产生的原因以及解决方法。 单片机...

Global site tag (gtag.js) - Google Analytics