指针究竟存储了什么? (C ++)

时间:2009-06-13 17:46:57

标签: c++ pointers overhead

我知道指针存储了它们指向的值的地址,但是如果直接在屏幕上显示指针的值,则会得到一个十六进制数字。如果数字正是指针存储的数字,那么在说

pA = pB; //both are pointers
你正在复制地址。那么在使用像intbool这样的非常小的项目时,使用指针会不会有更大的开销?

8 个答案:

答案 0 :(得分:13)

指针基本上只是一个数字。它将地址存储在数据所在的RAM中。指针本身非常小(可能与32位体系结构上的int大小相同,64位上为long

虽然在使用int *int不会节省任何空间,但您是正确的。但这不是重点(没有双关语意)。指针在那里你可以有引用到事物,而不仅仅是使用的东西

答案 1 :(得分:4)

内存地址。

这是内存中其他东西 的位置。

指针通常是处理器的字大小,因此它们通常可以在一个指令周期内移动。简而言之,它们很快。

答案 2 :(得分:3)

正如其他人所说,指针存储的内存地址“只是一个数字”,但这是一个抽象。根据处理器架构,它可能不止一个数字,例如必须添加的基数和偏移量取消引用指针。在这种情况下,开销略高于地址是单个数字。

是的,通过指针直接访问int或bool会产生开销,处理器可以将变量放在寄存器中。指针通常用于间接值超过任何开销的地方,即遍历数组。

我一直在指时间开销。不确定OP是否更关注空间或时间开销。

答案 3 :(得分:1)

数字是指其在内存中的地址。指针的大小通常是计算机体系结构的原生大小,因此与任何其他基本类型相比,没有额外的开销。

答案 4 :(得分:1)

在某些体系结构上,字符指针会产生额外的开销,因为该体系结构仅支持寻址字(32位或64位值)。因此,指向字符的指针被存储为字地址和该字中字符的偏移量。取消引用指针涉及获取单词,然后移动并屏蔽它的值以提取字符。

答案 5 :(得分:0)

内存中的地址。指向某个地方! : - )

答案 6 :(得分:0)

让我从基础开始。首先,您必须知道变量是什么以及如何使用它们。

变量基本上是内存位置(通常包含一些值),我们使用一些标识符(即变量名称)来引用该内存位置并使用该位置的值。

为了更好地理解它,假设我们希望来自存储器单元的信息存在于相对于当前变量的某个位置。我们可以使用标识符从附近的单元格中提取信息吗? 不会。因为标识符(变量名称)只会给出该特定单元格中包含的值。

但是,如果以某种方式我们可以获得存在此变量的内存地址,那么我们可以轻松地移动到附近的位置并使用它们的信息(在运行时)。

这是指针发挥作用的地方。它们用于存储该变量的位置,以便我们可以在需要时使用其他地址信息。

语法:要存储变量的地址,我们只需使用& (地址)运营商。

foo = &bar 

这里foo存储变量bar的地址。

现在,如果我们想知道该地址的值,该怎么办?

为此,我们可以简单地使用 *(取消引用)运算符

value = *foo

既然我们必须存储变量的地址,那么在变量的情况下,我们需要的内存与我们需要的内容相同。这意味着指针也以与其他变量相同的方式存储在内存中,因此就像变量一样,我们也可以将指针的地址存储到另一个指针中。

答案 7 :(得分:0)

是的,在速度和内存方面都是正确的。

指针总是比标准的int占用更多的字节,尤其是boolchar数据类型。在现代计算机上,指针通常是64位,比char高8倍。

这意味着分配foobar要慢得多,因为我们需要让操作系统为我们处理更多的内存分配:

struct Foo
{
    char * single_character;
    bool * single_bool;
};

struct Bar
{
    char single_character;
    bool single_bool;
};

#include <vector>

int main()
{
    int size = 1000000;
    std::vector<Foo> foo(size);
    std::vector<Bar> bar(size);

    return 0;
}

正如dmckee所指出的,一个字节bool的单个副本和一个指针的单个副本的确一样快:

bool num1, num2,* p1, * p2;
num1 = num2; // this takes one clock cycle
p1 = p2; // this takes another

正如dmckee所建议的,这很可能是由于现代64位寄存器所致。

但是,复制intboolchar的数组可以更快,因为我们可以将它们的倍数压缩到寄存器中:

#include <iostream>

int main ()
{
    const int n_elements = 100000 * sizeof(int64_t);

    bool A[n_elements];
    bool B[n_elements];

    int64_t * A_fast = (int64_t *) A;
    int64_t * B_fast = (int64_t *) B;

    const int n_quick_elements = n_elements / sizeof(int64_t);

    for (int i = 0; i < 10000; ++i)
        for (int j = 0; j < n_quick_elements; ++j)
            A_fast[j] = B_fast[j];

    return 0;
}

STL容器和其他好的库使用type_traitsis_trivially_copyable)和std::memcopy为我们做这种事情。以错误的幌子使用总是更快的点可能会阻止这些库的优化。

结论:在这些示例中看起来似乎很明显,但是当您需要访问原始对象时,仅对基本数据类型使用指针/引用。