【问题标题】:Address values are not having exact difference as structure length defined. [C]地址值与定义的结构长度没有精确的差异。 [C]
【发布时间】:2019-01-25 17:22:57
【问题描述】:
  1. 定义了一个包含一个变量的结构。长度为 51。
  2. 为此分配 4 个内存块。并听取用户的意见。
  3. 使用变量的地址打印输出。
  4. 两个地址相差33,不是51吗?

        NULL_NAME =  51
    
    /*Define structure to hold players name.*/
    typedef struct{
        char name [NULL_NAME];
    } player;
    
    players=(player*) malloc(4*sizeof(player));
    
    for(int i=0;i<4;i++){
       scanf("%s",p[i].name);
    }
    
    for(int j=0;j<4;j++){
       printf("%s \n",players[j].name);
       printf("%p \n",&players[j].name);
    }
    

输出:-

海合会: gcc --版本 gcc (Debian 6.3.0-12) 6.3.0 20170406 版权所有 (C) 2016 Free Software Foundation, Inc. 这是免费软件;请参阅复制条件的来源。没有 保修单;甚至不是为了适销性或特定用途的适用性。

【问题讨论】:

  • 请正确格式化您的代码并发布一个可以编译的真实程序
  • 请格式化您的帖子并包含一个可读的minimal reproducible example
  • 提示:十六进制的 33 是​​什么,转换为十进制?
  • 33 十六进制 = 3×16+3 = 51

标签: c memory-management dynamic-memory-allocation memory-address


【解决方案1】:

当使用带有 %p 的 printf 时,它会将指针地址打印为十六进制。这也在以 0x (十六进制前缀)开头的打印地址上注明。这就是为什么你得到 33(十六进制)的偏移量,即 51 个字节。

要将偏移量视为十进制值,请在最后一个 for 循环中添加以下行:

if ( j > 0 )
     printf(" offset is %ld\n", (players[j].name-players[j-1].name) );

你会得到输出 51(十进制)

【讨论】:

  • 它可以工作,但 C 标准不保证可以工作:(players[j].name-players[j-1].name) 在技术上具有未定义的行为,因为您减去了 2 个不指向同一个数组的指针。你应该使用(uintptr_t)players[j].name - (uintptr_t)players[j - 1].name
  • @chqrlie:这也不能保证。 C 标准不保证将指针转换为uintptr_t 会产生平面地址空间中地址的简单表示。更好的是(char *) &amp;players[j] - (char *) &amp;players[j-1],因为任何对象指针都可以转换为字符指针,它们都是指向同一个对象(player 的数组)的指针,不同之处在于字节数(作为ptrdiff_t).
  • @EricPostpischil:我想你是对的:C11 6.5.6p9 中的标准语言有点模棱两可:当减去两个指针时,两个指针都应该指向同一个数组的元素对象,或数组对象的最后一个元素... 它并没有说指针必须具有类型指向数组元素类型的指针。但是请注意 (char *)&amp;players[j]players[j].name 相同,因为指向结构的指针可以安全地转换为指向其第一个成员的指针,反之亦然,因此 OP 语法也应该没问题,但这些指针并不指向到同一个数组。
猜你喜欢
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多