我得到了结构:
typedef struct
{
int a;
int b;
int c;
}Z;
代码:
int main()
{
Z *a = (Z*)malloc(sizeof(Z)*8);
Z *b = (Z*)malloc(sizeof(Z)*8);
printf("%lu\n", sizeof(Z));
printf("%p %p\n", b, a);
printf("%lu\n", b - a);
}
输出:
12
0x89a080 0x89a010
12297829382473034420
为什么最后一行的价值如此巨大?实际地址差异是0x70(16个字节的堆分配头加上数组a的12 * 8个字节的元素),所以从指针的算术我期望值0x70 / 12 = 9.(3)或9转换为整数。我知道减去指针不指向相同的数组,但我期望更合理的结果,这将让我知道内存映射的样子。 它是在64b Ubuntu和gcc 4.8.2上编译的。
组件:
.file "aa.c"
.section .rodata
.LC0:
.string "%lu\n"
.LC1:
.string "%p %p\n"
.text
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $96, %edi
call malloc
movq %rax, -16(%rbp)
movl $96, %edi
call malloc
movq %rax, -8(%rbp)
movl $12, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movq -16(%rbp), %rdx
movq -8(%rbp), %rax
movq %rax, %rsi
movl $.LC1, %edi
movl $0, %eax
call printf
movq -8(%rbp), %rdx
movq -16(%rbp), %rax
subq %rax, %rdx
movq %rdx, %rax
sarq $2, %rax
movq %rax, %rdx
movabsq $-6148914691236517205, %rax
imulq %rdx, %rax
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
答案 0 :(得分:5)
使用不相关的指针(如a
和b
指针)进行指针运算是undefined behavior。
答案 1 :(得分:5)
从草案1570开始,这是
§6.5.6加法运算符
- 当减去两个指针时,都指向同一个数组对象的元素,或者指向数组对象的最后一个元素;结果是两个数组元素的下标的差异。结果的大小是实现定义的,其类型(有符号整数类型)在
醇>ptrdiff_t
标头中定义为<stddef.h>
。如果结果在该类型的对象中无法表示,则行为未定义。换句话说,如果表达式P
和Q
分别指向数组对象的第i个和第j个元素,则表达式(P)-(Q)
具有值{{1如果值适合i−j
类型的对象。此外,如果表达式P指向一个元素 一个数组对象或一个超过数组对象的最后一个元素,并且表达式ptrdiff_t
指向 对于同一个数组对象的最后一个元素,表达式Q
具有相同的元素 值为((Q)+1)-(P)
和((Q)-(P))+1
,如果为,则值为零 表达式-((P)-((Q)+1))
指向数组对象的最后一个元素,即使是 expressionP
不指向数组对象的元素。
你不能假设指针是连续的,但是如果它们是实际的问题就是指针运算的方式,因为poitners有类型(Q)+1
和Z
。
请查看此示例以说明我的意思
(void *)b - (void *a) != b - a
请记住为Z *a;
Z *b;
Z *a = malloc(sizeof(Z) * 16);
if (a == NULL)
return -1;
b = a + 8;
printf("%lu\n", sizeof(Z));
printf("%p, %p\n", b, a);
printf("%lu\n", (ptrdiff_t)(b - a)); /* this will give wrong result */
printf("%lu\n", (ptrdiff_t)((void *)b - (void *)a));
类型添加stddef.h
。