【问题标题】:Pointer to address and Memory Stack指向地址和内存堆栈的指针
【发布时间】:2013-02-05 18:18:50
【问题描述】:
void EventsStack::push(Event *e){
    EventNode *q = new EventNode();
    q->data = e;
    q->next = _top;
    _top = q;
}

void main() {
    EventsStack eventStack;
    Event e1(1);
    eventStack.push(&e1);
    Event e2(2);
    eventStack.push(&e2);
}

第一个问题:我什么时候做

eventStack.push(&e1);

我是否将 e1 的地址发送到 push 函数,而 push 函数将其作为指针接收?好像我在做:

Event *e = 1000 (1000 is the offset (address) of e1 for example on the stack)

?

第二个问题:我被要求在运行 main 函数时说明堆栈。当我到达线路时

eventStack.push(&e1);

是否分配了一个 4 字节返回地址和一个指向 e1 的 4 字节指针作为函数的激活帧,或者在这种情况下没有激活帧,因为 eventStack 是 EventsStack 类的对象,而 push 是它的成员函数之一?

【问题讨论】:

标签: c++ memory-management


【解决方案1】:

关于您的第一个问题:表达式&e1 需要 e1的地址,是一个指针。换句话说,e1 具有Event 类型,&e1 具有Event* 类型,以及诸如此类的值 取消引用它(一元 * 运算符)将具有 与使用e1 的效果相同。这就是你传递给 push 的内容 功能。

并且指针不能只是堆栈上的偏移量,因为它 必须可以从其他地方访问该对象, 堆栈不一定可用。最现代的 台式机使用线性寻址,这意味着 指针只是一个整数,但这并不总是 情况,在某些嵌入式处理器上可能并非如此 (以及某些大型机上的历史原因)。

关于第二个问题:形式上,完全是 未指定的如何函数被调用。需要的是 编译器把返回地址和参数 被调用函数可以找到它们的地方。在里面 表达式eventStack.push( &e1 ),函数有两个 参数,eventStack 的地址(这将成为 this 函数中的指针)和表达式 &e1。如何 编译器传递这些变化很大,几乎 总是取决于他们的类型,但通常,在大多数现代 机器,前 3 到 5 个参数将进入机器 如果它们适合,则注册(并且您传递的两个地址都将 fit),所以所有被压入机器堆栈的都是返回 地址。并且参数通常不被认为是 当前帧,尽管在一些较旧的处理器上,编译器 确实如此对待他们。 (你说你被“要求说明 堆栈”。问题是否涉及特定机器 建筑,还是什么?堆栈上实际发生的事情将 编译器之间的差异很大,Linux 下的 g++ 会 经常做一些与 Visual Studios 完全不同的事情, 即使在同一处理器上运行。)

【讨论】:

  • 当类被称为 eventstack 时,事情会变得更糟......堆栈是否引用了该对象?还是指机器的调用栈。
  • @thang 这是另一种可能性。提到一个带有数值的地址,让我觉得他的意思是生成的代码用来支持递归调用的堆栈,但你永远不知道。无论如何,我认为关键点是 1) EventStack::push 接受两个参数,而不是一个,以及 2) 参数的传递方式非常依赖于实现,并且通常仅在没有其他替代方案可用时才使用将它们推送到机器堆栈上。值得一提的是,在现代机器上,地址通常是 8 个字节,而不是 4 个(当然,它们可以是任意大小)。
【解决方案2】:

关于您的第一个问题,是的:& 运算符产生您的事件的内存地址。

关于你的第二个问题,嗯,很复杂。您所做的描述似乎表明了堆栈如何工作的潜在混淆。我强烈建议您阅读有关该主题的一些介绍性材料,它会让您有更深入的理解。

如果你去谷歌一下,几个小时后你就能回答你自己的问题了:)。

【讨论】:

  • 其实第一个问题的答案可能不是肯定的。 1000 是 e1 的偏移量(地址),例如在堆栈上....听起来对吗?
  • 根据我的教授们所说...是的。事件 e1(1)。在堆栈上创建 e1,其起始地址为 1000。我将 &e1 发送到作为其地址的函数:1000。该函数将其作为 Event* e。因此:事件 *e = 1000 或....我错了吗?
  • @TheNotMe 在堆栈上创建e1 是合理的,即使没有硬件堆栈,因为局部变量的生命周期表现得好像它们在堆栈上(必须是如果没有直接的硬件支持,则以某种方式模拟)。地址 1000 听起来像是在用抽象机器而不是任何具体的硬件来解释事物。因此,您必须查看此抽象机器的规范以获得确切答案,因为我们无权访问这些规范。
猜你喜欢
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-03
相关资源
最近更新 更多