2013-02-22 209 views
0

有没有办法在C中添加两个内存地址或将一个内存地址乘以一个数字?地址加法和乘法C

如果是这样,怎么样?例如,假设我有地址:

void * p = (void *) 0x80000000; 

而且我想乘以2或添加另一个地址,以更改变量的当前地址!

+1

在某些平台上,类型转换可以工作,但它的含义较少,也可能'sizeof(int)'不可以='sizeof(void *)' – 2013-02-22 16:00:27

+0

'(void *)0x80000000'很可能*不是*地址。 – Sebivor 2013-02-22 16:49:21

+0

您在其中一个答案的评论中描述的问题,即管理内存并将内存区域划分为多个部分,不需要添加地址或将地址乘以数字。它只需要在整数(而不是地址)上添加整数(或从中减去整数)地址和普通算术。 – 2013-02-22 16:55:30

回答

1

0x28ff44不是“变量的地址”p,它只是变量的值。由于该变量是一个指针,因此该值是一个地址。你当然可以修改的值,就好像它是一个整数,通过转换为/从整数,但为什么你会想这样做?

这里是一个傻函数指针的值增加一倍:

void * double_address(void *p) 
{ 
    const intptr_t pi = (intptr_t) p; 

    return (void *) 2 * pi; 
} 
+0

0x80000000呢?没有转换是不可能的? – feruz 2013-02-22 16:03:11

+0

@feruz不,没有转换,你只能在指针上加整数(或者从指针中减去整数或指针) - 在狭窄的范围内。但是,由于没有已知的合理用途来增加指针或增加指针指针,所以迄今为止它还没有被错过。 – 2013-02-22 16:13:08

+0

地址是一个指向对象的指针值,但并非所有的指针值都是地址。 'void * foo = 0;'foo的值不是地址,因为它不指向对象。 – Sebivor 2013-02-22 16:18:38

1

不能有意义*用C用数字或其他地址添加两个地址在一起,或乘一个地址。允许的两个操作是减去指向连续内存块的地址,并向地址添加正整数或负整数。将两个地址相乘或相加是没有意义的,因为结果不会产生有意义的地址。


*想想这样说:因为地址只是数字,因为数学,您可以繁殖并自由添加数字,并不意味着数学运算的结果会产生什么有意义。例如,你当然可以将机场跑道的长度以英寸加上飞机油箱的容量,单位为加仑。由于这种奇怪的计算,你会得到一个数字,但它仍然只是一个数字序列,在物理世界中没有任何意义。

+0

这样思考并不一定有帮助。 “标签架构Symbolics Lisp Machine甚至没有传统的数字指针;它使用一对(基本上不存在的句柄)作为C空指针。” - http://c-faq.com/null/machexamp.html – Sebivor 2013-02-22 16:15:22

+0

@modifiablelvalue''的句柄在内部最终表示为* some *无意义的数字。一旦你获得了这个数字,你就可以将它乘以计算器屏幕上的任何东西,并从中得到一个数字序列。毋庸置疑,新的数字序列将与原始序列一样毫无意义。 – dasblinkenlight 2013-02-22 16:37:29

0

我知道你唯一能做的就是给指针添加一个整数值,这将导致指针在内存中移动sizeof(pointertype)

例子:

int* ptr; 
int arr[2]; 
//put some values in arr; 
ptr = &arr[0]; 
ptr = ptr + 1; // will cause the pointer to move along in the array by `sizeof(int)` 

中添加或我从来没有听说过或看到过任何其他方式乘以地址。

0

你能解释一下你想做什么吗?

您可以将变量复制到另一个指针,然后设置为设置第一个变量。

// Creates new pointer with new address (why ?) 
void* new_var_ptr = malloc(<size_of_p>); 

// Copy content of "p" address to "new_var_ptr" address 
memcpy(new_var_ptr, p, <size_of_p>); 

// Set "p" content to NULL (optional) 
memset(p, 0, <size_of_p>); 

// Set "p" to NULL (optional) 
p = NULL 

然后“new_var_ptr”将指向p的前一个内容。

+0

以及我试图管理内存,选择/滑入某些部分!我有地址和长度的开始。我以为我可以从头开始,然后划分相同的部分,并添加下一个片段..我希望你有这个想法?! – feruz 2013-02-22 16:07:47

0

在C中添加两个地址是无效的,而且很可能从来没有你想做的事。您可能想要从一个指针添加OFFSET到另一个指针,例如:

char *ptr1 = ...; 
char *ptr2 = ...; 
ptrdiff_t d = ptr1 - ptr2; 
char *ptr3 = ptr2 + d; 

[注意,以上仅是正式有效如果ptr1ptr2指向“相同的对象” - 即,相同的分配或在同一阵列或相似]

乘以一个指针通过另一个指针会更加毫无意义[原谅双关语!]。由于指针往往是相当大的数字,乘以两个指针的乘积也可能溢出结果,使其变得更加无用。