文档章节

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

郑树新
 郑树新
发布于 2014/09/03 12:10
字数 1016
阅读 12
收藏 0

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

 

© 著作权归作者所有

郑树新

郑树新

粉丝 104
博文 87
码字总数 161171
作品 2
昌平
程序员
私信 提问
Objective-C基本数据类型

Objective-C基本数据类型 因为Objective-C(下称ObjC)本质是一个C语言的超集,所以所有C语言支持的基本数据类型,ObjC同样支持,并且ObjC还支持一些其它的常用数据类型。 int 与 NSIntege...

秋刀生鱼片
2016/06/15
0
0
结构体嵌套对齐

64 位的优点:64 位的应用程序可以直接访问 4EB 的内存和文件大小最大达到4 EB(2 的 63 次幂);可以访问大型数据库。本文介绍的是64位下C语言开发程序注意事项。 1. 32 位和 64 位C数据类型...

pingglala
2016/11/17
0
0
__attribute__ ((packed))

网络通信通常分为基于数据结构的和基于流的。HTTP协议就是后者的一个例子。 有时为了提高程序的处理速度和数据处理的方便,会使用基于数据结构的通信(不需要对流进行解析)。但是,当需要在...

慎思
2012/08/14
0
0
C、C++和java中各种数据类型的长度

C 32位机 64位机 char 1 1 int 4 4 long 4 8 float 4 4 double 8 8 char 4 8 二、C++ int型字长问题: ① C/C++规定int字长和机器字长相同; ② 操作系统字长和机器字长未必一致; ③ 编译器...

王大豆
2015/09/02
529
0
C语言数据类型

C语言数据类型 Mindy2017-03-3049 阅读 数据类型C语言 速查表: char -128 ~ +127 (1 Byte) short -32767 ~ + 32768 (2 Bytes) unsigned short 0 ~ 65536 (2 Bytes) int -2147483648 ~ +214......

Mindy
2017/03/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java思维导图整理

jmm https://www.edrawsoft.cn/viewer/public/s/b0178374373697; redis https://www.edrawsoft.cn/viewer/public/s/5691c269955848 map https://www.edrawsoft.cn/viewer/public/s/b67533638......

流光韶逝
10分钟前
2
0
Gnu/Linux 防止暴力扫描及其它

RedHat7 手工脚本: # iptables iptables -A INPUT -i eno16777728 -p tcp -m multiport --destination-port 135,136,137,138,139,445,4899,1900 -j LOG iptables -A INPUT -p tcp -m multip......

晒太阳的小猪
33分钟前
14
0
OSChina 周一乱弹 —— 满周岁就去挣钱!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @ tom_tdhzz:一直期待了很久,这是第二次来圆明园,也是特意来这里,只是才发现只有历史现实不在了。#今日歌曲推荐# 分享王晰的单曲《南屏晚...

小小编辑
50分钟前
613
11
解决Structure needs cleaning

简介 今天在同步文件的时候有一个目录突然报错 Structure needs cleaning 百度了一下发现使用xfs_repair可以解决 操作 因为我做的是raid5 ,可能是昨天我重启了机器的缘故,所以我要做的是先...

bboysoulcn
今天
6
0
Dubbo服务暴露与注册

前面的文章中,我们讲解了Dubbo是如何进行配置的属性的初始化的,并且讲到,Dubbo最终会将所有的属性参数都封装为一个URL对象,从而以这个URL对象为基准传递参数。本文则主要讲解Dubbo是如何...

爱宝贝丶
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部