堆栈帧问题:Java 与 C++

发布于 2024-08-03 05:17:09 字数 1222 浏览 5 评论 0原文

Q1.在Java中,所有的对象、数组和类变量都存储在堆上?对于C++来说也是如此吗?数据段是堆的一部分吗?

下面的 C++ 代码怎么样?

class MyClass{
    private:
            static int counter; 
            static int number;
};

MyClass::number = 100;

Q2。据我的理解,编译器赋予特定值的变量存储在数据段中,未初始化的全局变量和静态变量存储在BSS(由符号启动的块)中。在这种情况下,静态的 MyClass::counter 被编译器初始化为零,因此它存储在 BSS 中,初始化为 100 的 MyClass::number 存储在数据段中。我的结论正确吗?

Q3。考虑以下代码:

void doHello(MyClass &localObj){   
// 3.1 localObj is a reference parameter, where will this get stored in Heap or Stack?
      // do something
}

void doHelloAgain(MyClass localObj){   
// 3.2 localObj is a parameter, where will this get stored in Heap or Stack?
      // do something
}

int main(){
      MyClass *a = new MyClass();  // stored in heap

      MyClass localObj;   
      // 3.3 Where is this stored in heap or stack?
      doHello(localObj);
      doHelloAgain(localObj);
}

我希望我已经向所有人明确了我的问题

编辑:

请参考此文章对 BSS 的一些了解

编辑1:将类名从 MyInstance 更改为 MyClass,因为它是一个糟糕的名称。真诚的道歉

编辑2:将类成员变量号从非静态更改为静态

Q1. In Java, all objects, arrays and class variables are stored on the heap? Is the same true for C++? Is data segment a part of Heap?

What about the following code in C++?

class MyClass{
    private:
            static int counter; 
            static int number;
};

MyClass::number = 100;

Q2. As far as my understanding goes, variables which are given a specific value by compiler are stored in data segment, and unintialized global and static variables are stored in BSS (Block started by symbol). In this case, MyClass::counter being static is initialized to zero by the compiler and so it is stored at BSS and MyClass::number which is initialized to 100 is stored in the data segment. Am I correct in making the conclusion?

Q3. Consider following piece of codes:

void doHello(MyClass &localObj){   
// 3.1 localObj is a reference parameter, where will this get stored in Heap or Stack?
      // do something
}

void doHelloAgain(MyClass localObj){   
// 3.2 localObj is a parameter, where will this get stored in Heap or Stack?
      // do something
}

int main(){
      MyClass *a = new MyClass();  // stored in heap

      MyClass localObj;   
      // 3.3 Where is this stored in heap or stack?
      doHello(localObj);
      doHelloAgain(localObj);
}

I hope I have made my questions clear to all

EDIT:

Please refer this article for some understanding on BSS

EDIT1: Changed the class name from MyInstance to MyClass as it was a poor name. Sincere Apologies

EDIT2: Changed the class member variable number from non-static to static

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

满意归宿 2024-08-10 05:17:09

据我所知,这有点简化,但大部分是准确的。

在Java中,所有对象都在堆上分配(包括所有成员变量)。大多数其他内容(参数)都是引用,引用本身与本机类型(整数、长整型等)一起存储在堆栈中,但字符串除外,字符串更像是对象而不是本机类型。

在 C++ 中,如果您要使用“new”关键字分配所有对象,那么情况与 java 几乎相同,但在 C++ 中存在一种独特的情况,因为您可以在堆栈上分配对象(您并不总是必须使用“新”)。

另请注意,Java 的堆性能比 C 的堆性能更接近 C 的堆栈性能,垃圾收集器做了一些非常聪明的事情。它仍然不如堆栈好,但比堆好得多。这是必要的,因为 Java 无法在堆栈上分配对象。

This is somewhat simplified but mostly accurate to the best of my knowledge.

In Java, all objects are allocated on the heap (including all your member variables). Most other stuff (parameters) are references, and the references themselves are stored on the stack along with native types (ints, longs, etc) except string which is more of an object than a native type.

In C++, if you were to allocate all objects with the "new" keyword it would be pretty much the same situation as java, but there is one unique case in C++ because you can allocate objects on the stack instead (you don't always have to use "new").

Also note that Java's heap performance is closer to C's stack performance than C's heap performance, the garbage collector does some pretty smart stuff. It's still not quite as good as stack, but much better than a heap. This is necessary since Java can't allocate objects on the stack.

冷清清 2024-08-10 05:17:09

Q1

Java也在堆栈上存储变量,但类实例在堆上分配。在 C++ 中,您可以自由地在堆栈或堆上分配类实例。通过使用 new 关键字,您可以在堆上分配实例。

数据段不是堆的一部分,而是在进程启动时分配的。堆用于动态内存分配,而数据段是静态的并且内容在编译时已知。

BSS段只是一种优化,其中属于该数据段的所有未初始化或初始化为零的数据(例如字符串、常数等)都被移动到BSS段。数据段必须嵌入到可执行文件中,并且通过将“所有零”移动到末尾,可以将它们从可执行文件中删除。当加载可执行文件时,BSS 段被分配并初始化为零,并且编译器仍然能够知道 BSS 段内的各种缓冲区、变量等的地址。

Q2

MyClass::number 存储在分配 MyClass 类的实例的位置。它可以位于堆上或堆栈上。请注意在第三季度中,a 如何指向在堆上分配的 MyClass 实例,而 localObj 是在堆栈上分配的。因此,a->number 位于堆上,而 localObj.number 位于堆栈上。

由于 MyClass::number 是一个实例变量,您不能像这样分配它:

MyClass::number = 100;

但是,您可以分配 MyClass::counter 因为它是静态的(除了它是私有的) :

MyClass::counter = 100;

Q3

当您调用doHello时,变量localObj(在main中)通过引用传递。 doHello 中的变量 localObj 引用堆栈上的该变量。如果您更改它,更改将存储在分配 main 中的 localObj 的堆栈中。

当您调用doHelloAgain时,变量localObj(在main中)被复制到堆栈上。在 doHelloAgain 内部,变量 localObj 在堆栈上分配,并且仅在调用期间存在。

Q1

Java also stores variables on the stack but class instances are allocated on the heap. In C++ you are free to allocate your class instances either on the stack or on the heap. By using the new keyword you allocate the instance on the heap.

The data segment is not part of the heap, but is allocated when the process starts. The heap is used for dynamic memory allocations while the data segment is static and the contents is known at compile time.

The BSS segment is simply an optimization where all the data belongning to the data segment (e.g. string, constant numbers etc.) that are not initialized or initialized to zero are moved to the BSS segment. The data segment has to be embedded into the executable and by moveing "all the zeros" to the end they can be removed from the executable. When the executable is loaded the BSS segment is allocated and initialized to zero, and the compiler is still able to know the addresses of the various buffers, variables etc. inside the BSS segment.

Q2

MyClass::number is stored where the instance of MyClass class is allocated. It could be either on the heap or on the stack. Notice in Q3 how a points to an instance of MyClass allocated on the heap while localObj is allocated on the stack. Thus a->number is located on the heap while localObj.number is located on the stack.

As MyClass::number is an instance variable you cannot assign it like this:

MyClass::number = 100;

However, you can assign MyClass::counter as it is static (except that it is private):

MyClass::counter = 100;

Q3

When you call doHello the variable localObj (in main) is passed by reference. The variable localObj in doHello refers back to that variable on the stack. If you change it the changes will be stored on the stack where localObj in main is allocated.

When you call doHelloAgain the variable localObj (in main) is copied onto the stack. Inside doHelloAgain the variable localObj is allocated on the stack and only exists for the duration of the call.

香草可樂 2024-08-10 05:17:09

在 C++ 中,对象可以在堆栈上分配...例如,Q3 主例程中的 localObj。

我感觉到类与实例之间存在一些混淆。 “MyInstance”作为变量名比类名更有意义。在您的 Q1 示例中,“number”存在于 MyInstance 类型的每个对象中。 “计数器”由所有实例共享。 “MyInstance::counter = 100”是有效的分配,但“MyInstance::number = 100”不是,因为您尚未指定
应该将其“number”成员分配给哪个对象。

In C++, objects may be allocated on the stack...for example, localObj in your Q3 main routine.

I sense some confusion about classes versus instances. "MyInstance" makes more sense as a variable name than a class name. In your Q1 example, "number" is present in each object of type MyInstance. "counter" is shared by all instances. "MyInstance::counter = 100" is a valid assignment, but "MyInstance::number = 100" is not, because you haven't specified
which object should have its "number" member assigned to.

冬天旳寂寞 2024-08-10 05:17:09

Q1。在 Java 中,所有对象、数组和
类变量存储在
堆?对于C++来说也是如此吗?是
数据段是堆的一部分?

不,数据部分与堆是分开的。基本上,数据部分是在加载时分配的,之后所有内容都有一个固定的位置。此外,对象可以在堆栈上分配。

对象位于堆上的唯一时间是使用 new 关键字,或者使用 malloc 系列函数中的某些内容。

第二季度。据我的理解,
被赋予特定的变量
编译器的值存储在数据中
段,以及未初始化的全局和
静态变量存储在BSS中
(块由符号开始)。在这个
情况下,MyInstance::counter 是静态的
被编译器初始化为零
所以它存储在 BSS 中并且
MyInstance::number 是
初始化为 100 存储在
数据段。我的做法正确吗
结论?

是的,您对BSS部分的理解是正确的。但是,由于 number 不是静态的,因此代码:

MyInstance::number = 100;

不合法,因此需要将其设置为静态或在构造函数中正确初始化。如果在构造函数中初始化它,则无论分配拥有的对象,它都将存在。如果将其设为静态,它将最终出现在数据部分......如果有的话。通常,static const int 变量可以直接内联到所使用的代码中,这样根本不需要全局变量。

第三季度。考虑以下代码:...

void doHello(MyInstance &localObj){

localObj 是对传递的对象的引用。据你所知,没有存储,它指的是传递的变量在哪里。实际上,在底层,可以在堆栈上传递一个指针来促进这一点。但如果可以的话,编译器也可以轻松地对其进行优化。

void doHelloAgain(MyInstance localObj){

传递参数的副本被放置在堆栈上。

MyInstance localObj;
// 3.3 Where is this stored in heap or stack?

localObj 在堆栈上。

Q1. In Java, all objects, arrays and
class variables are stored on the
heap? Is the same true for C++? Is
data segment a part of Heap?

No, the data section is separate from the heap. Basically, the data section is allocated at load time, everything there has a fixed location after that. In addition, objects can be allocated on the stack.

The only time objects are on the heap is if you use the new keyword, or if you use something from the malloc family of functions.

Q2. As far as my understanding goes,
variables which are given a specific
value by compiler are stored in data
segment, and unintialized global and
static variables are stored in BSS
(Block started by symbol). In this
case, MyInstance::counter being static
is initialized to zero by the compiler
and so it is stored at BSS and
MyInstance::number which is
initialized to 100 is stored in the
data segment. Am I correct in making
the conclusion?

Yes, your understanding of the BSS section is correct. However, since number isn't static the code:

MyInstance::number = 100;

isn't legal, it needs to be either made static or initialized in the constructor properly. If you initialize it in the constructor, it will exist wherever the owning object is allocated. If you make it static, it will end up in the data section... if anywhere. Often static const int variables can be inlined directly into the code used such that a global variable isn't needed at all.

Q3. Consider following piece of codes: ...

void doHello(MyInstance &localObj){

localObj is a reference to the passed object. As far as you know, there is no storage, it refers to wherever the variable being passed is. In reality, under the hood, a pointer may be passed on the stack to facilitate this. But The compiler may just as easily optimize that out if it can.

void doHelloAgain(MyInstance localObj){

a copy of the passed parameter is placed on the stack.

MyInstance localObj;
// 3.3 Where is this stored in heap or stack?

localObj is on the stack.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文