如何在c ++中为指针分配常量地址?

时间:2013-05-30 18:29:33

标签: c++ pointers const

我想检查当我增加/减少指针值时如何更改指针地址。

我的代码是:

void pointers_plus_minus()
{
    char *c = (char *) 0x7fff80ccd35c;
    int *i = (int *) 0x7fff80ccd35c;

    c++;
    i++;

    cout << "char pointer" << c << endl;
    cout << "int pointer" << i << endl;
}

但是这段代码给了我Segmentation fault (core dumped)

我理解地址有问题,但不清楚是什么。怎么解决?我正在使用64位Ubuntu。

3 个答案:

答案 0 :(得分:9)

你不能操作指针,就像它们是整数一样(好吧,不是在定义明确的上下文之外)。

如果指针指向您拥有的数组内,则只允许c++i++

糟糕,我认为这实际上定义得很好,因为1个元素被视为1的数组,并且允许你通过一个元素超越数组的末尾。但是从该指针读取仍未定义。

无论如何,虽然未定义,但崩溃可能是因为cout << c尝试打印出字符串而不是指针。将其投放到void*

cout << "char pointer" << static_cast<void*>(c) << endl;

虽然这会满足你的好奇心,这很好,但它仍然是未定义的,不应该这样做。

答案 1 :(得分:5)

你问过如何为指针分配一个常量地址,但是这样做(a)是非常不可移植的,而且(b)不一定能达到你的目的,即看到增加指针的效果。

这是一个可以满足你的好奇心而不会因未定义的行为而爆炸的程序:

#include <iostream>
int main() {
    const int len = 10;
    char char_array[len];
    int int_array[len];

    char *cp = char_array;
    for (int i = 0; i <= len; i ++) {
        std::cout << "cp = " << static_cast<void*>(cp) << "\n";
        cp ++;
    }

    std::cout << '\n';

    int *ip = int_array;
    for (int i = 0; i <= len; i ++) {
        std::cout << "ip = " << static_cast<void*>(ip) << "\n";
        ip ++;
    }
}

我(64位)系统的输出是:

cp = 0x7fffaa5ddc30
cp = 0x7fffaa5ddc31
cp = 0x7fffaa5ddc32
cp = 0x7fffaa5ddc33
cp = 0x7fffaa5ddc34
cp = 0x7fffaa5ddc35
cp = 0x7fffaa5ddc36
cp = 0x7fffaa5ddc37
cp = 0x7fffaa5ddc38
cp = 0x7fffaa5ddc39
cp = 0x7fffaa5ddc3a

ip = 0x7fffaa5ddc00
ip = 0x7fffaa5ddc04
ip = 0x7fffaa5ddc08
ip = 0x7fffaa5ddc0c
ip = 0x7fffaa5ddc10
ip = 0x7fffaa5ddc14
ip = 0x7fffaa5ddc18
ip = 0x7fffaa5ddc1c
ip = 0x7fffaa5ddc20
ip = 0x7fffaa5ddc24
ip = 0x7fffaa5ddc28

关于此的一些注释:

指针增量有效,因为每个指针始终指向正确类型的数组元素,或者只是指向它的末尾。 (你可以在数组的末尾构造一个指针;你不能取消引用这样的指针。)

打印类型void*的指针时生成的输出是实现定义的。在我的系统上,它恰好是指针值的十六进制表示,被解释为它是一个整数 - 这可能是它最常用的方式。

您可以看到char*指针每次增加1,int*指针增加4.在我的系统(可能是您的系统)上,指针存储为字节地址。指针算术以指向类型为单位定义,而不是以字节为单位。增加int*指针会使其指向前一个位置之后的内存位置sizeof (int)个字节 - 在本例中为4个字节。所有指针算术都是这样定义的; ptr2 - ptr1为您提供两个地址之间的元素数量(ptr1ptr2指向的数量)。

打印的具体值告诉您有关如何在系统上管理内存地址的内容。指针和整数之间的映射通常会反映系统的内存模型。该模型主要针对具体实施。

答案 2 :(得分:-2)

Seg错误,我在堆栈溢出旁边最喜欢的错误消息,就是当你试图写入非法内存空间时。也就是说,你怎么能保证当你的程序被加载到内存中时你的堆栈/堆空间落在你想要保留的区域内,更何况你甚至想要这样做?这可以在Assembly中完成,因为你对硬件的访问权限要低得多,但我很怀疑它可以在C中完成(或者如果可以的话)。