一个C的指针问题

昨天写程序时发生了这样一件事:有一段代码,首先申请的x字节的内存,然后吧前面的部分当作一个结构体A,把剩下的当作缓存,用代码表示如下:

...
struct A* a = malloc(x);
void* buf = a+sizeof(struct A);
...

但是上面的代码缺不能工作,使用调试器发现buf指向的内存不是我们希望的a后面+sizeof(A),而是比这个要大很多的一个数。
吧代码改成这样,就正常工作了

...
struct A* a = malloc(x);
void* buf = ((char*)a)+sizeof(struct A);
...

虽然正常了,但是某熊很想知道为什么,如果有哪位看官知道麻烦说一声(拜
以上。

>_<|| 我手贱!!这个有问题!绝对有问题!!一般般啦,真的很一般般。还不错哦~小表扬一下!GJ!乃就是新世界的神様了,快去拯救世界吧! (1 votes, average: 4.00 out of 5)
Loading...

11 人次吐槽

  1. KC说道:
    骑着 Firefox 3.0.13 Firefox 3.0.13 和 Windows XP Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.13) Gecko/2009073022 Firefox/3.0.13 (.NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)

    MS和Struct的member有关

  2. liangent说道:
    骑着 IceWeasel 3.0.6 IceWeasel 3.0.6 和 Debian GNU/Linux Debian GNU/Linux
    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.11) Gecko/2009061212 Iceweasel/3.0.6 (Debian-3.0.6-1)

    网页下面那两个人太大了碍事……能不能给用户选择关掉……

    1. Bearice说道:
      骑着 Firefox 3.5.4 Firefox 3.5.4 和 Windows 7 Windows 7
      Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 GTB6 (.NET CLR 3.5.30729)

      嘛,本来下个版本会有的,不过下个版本什么时候会有呢?(远目

  3. reus说道:
    骑着 Google Chrome 3.0.195.27 Google Chrome 3.0.195.27 和 Windows 7 Windows 7
    Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.27 Safari/532.0

    因为前面那个指针的类型是 struct A*,所以加上一个整数的话(假设为n),返回的地址实际是a+n*sizeof(struct A)。后面强制转换成了(char*),其实就是一个字节,才会得到a+sizeof(struct A)。其实把a定义成void*不就好了么。。

  4. reus说道:
    骑着 Google Chrome 3.0.195.27 Google Chrome 3.0.195.27 和 Windows 7 Windows 7
    Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.27 Safari/532.0

    反正指针的加减运算,得到的地址是跟指针类型有关的。假设int是32位的,则一个int*类型的指针+1,等于char*类型的+4.

  5. WordPress 2.8 WordPress 2.8
    The Incutio XML-RPC PHP Library -- WordPress/2.8

    […]   此问题是由IcyBear提出的,原文地址在:http://blog.icybear.cn/2009/10/a-c-pointer-question.html […]

  6. Run说道:
    骑着 Firefox 3.5.4 Firefox 3.5.4 和 Windows XP Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4

    恩,易错点,记下了

  7. aini说道:
    骑着 Firefox 3.0.2 Firefox 3.0.2 和 Windows XP Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.2) Gecko/2008091620 Firefox/3.0.2

    这个问题很简单来……对于一个变量来说有三个要素:首地址,类型,值;
    而指针要标明类型的原因就是指针在进行加减移动的时候移动的是一个类型单位的距离,而不是字节数。
    也就是说当指针在进行加减运算的时候,所移动的字节数与指针的类型有关。所以说在强转之后的指针类型进行运算后才是想要的距离。而char类型的变量正好是1个字节。在转化为char型指针后,移动的距离正好是字节数。
    对于你提出的问题,最简单的办法是
    ……
    struct A* a = malloc(x);
    ++a;
    ……

    欧科?拜师吧……我等你……

  8. aini说道:
    骑着 Firefox 3.0.2 Firefox 3.0.2 和 Windows XP Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.2) Gecko/2008091620 Firefox/3.0.2

    汗……没仔细看回复,被“KingsamChen的废墟堆”这小子抢先了……

  9. Null说道:
    骑着 Firefox 3.6 Firefox 3.6 和 Windows XP Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)

    sizeof(struct A) 的到的数一般会大于结构体个成员占用内存之和,
    比如

    struct A
    {
    char a;
    };

    这时候,sizeof(struct A) ==4
    因为因为默认根据机器字节长进行对位,32位系统,一次处理32位字节,也就是 4byte,编译系统发现不够32位的就补够。

    主要是为了方便机器处理。当然有个宏可以强制对位长度改为8位。

  10. AnwuLac说道:
    骑着 ChromePlus 1.4.1.0 ChromePlus 1.4.1.0 和 Windows 7 Windows 7
    Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.126 Safari/533.4 ChromePlus/1.4.1.0

    差不多的吧,void* buf = a+sizeof(struct A);
    这个写成void* buf = a+1; 这样就可以的。C中的矢量加法,a+1 就表示 指针移动1个单位长度,a的单位是 struct A,就是移动sizeof(struct A)个字节。