标签: memory-layout

使用g ++编译器打印C++对象的布局

有没有办法使用g ++编译器或任何其他方法打印C++对象的布局.一个简化的例子(假设int需要4个字节)

class A{
  int a;
};

class B:public A{
  int b;
}
Run Code Online (Sandbox Code Playgroud)

所以输出就是

A-
0      4
+  a   +

B-
0      4      8
+ A.a  +  b   +
Run Code Online (Sandbox Code Playgroud)

理解对象的布局(在我的例子中是虚拟机代码)会很有用.

提前致谢.

问候,扎赫尔

c++ g++ memory-layout

11
推荐指数
2
解决办法
3079
查看次数

增加函数指针

我刚刚学习了函数指针(指向存储函数机器代码的地址的指针).这让我想到机器代码以及它如何存储在内存中.

机器代码是否连续存储在内存中,以便可以"手动"增加指针,直到它指向下一个/上一个函数?

这是调试器的作用吗?他让我"看到"程序计数器指向机器代码的位置?

结论:可以用函数指针编程一个原始调试器吗?

我理解这是对的,还是我离开了?

c function-pointers memory-layout

10
推荐指数
3
解决办法
3450
查看次数

为什么ELF入口点0x8048000不能通过"ld -e"选项更改?

跟进为什么ELF执行入口点虚拟地址为0x80xxxxx而不是0x0?为什么Linux程序的虚拟内存地址为0x8048000开始?,为什么我不能ld使用与默认值不同的入口点ld -e

如果我这样做,我会得到一个segmentation fault返回代码139,即使对于默认入口点附近的地址.为什么?

编辑:

我会更具体地提出这个问题:

        .text
        .globl _start    
_start:
        movl   $0x4,%eax        # eax = code for 'write' system call   
        movl   $1,%ebx          # ebx = file descriptor to standard output
        movl   $message,%ecx    # ecx = pointer to the message
        movl   $13,%edx         # edx = length of the message
        int    $0x80            # make the system call
        movl   $0x0,%ebx        # the status returned by 'exit'
        movl   $0x1,%eax        # eax = code for …
Run Code Online (Sandbox Code Playgroud)

linker elf memory-layout

10
推荐指数
1
解决办法
7295
查看次数

使用反射来确定.Net类型在内存中的布局方式

我正在尝试在C#中优化解析器组合器.当序列化格式与内存格式匹配时,一种可能的优化是仅对要在实例上解析的数据的(不安全)memcpy或甚至该类型的许多实例进行解析.

我想编写代码来确定内存中的格式是否与序列化格式匹配,以便动态确定是否可以应用优化.(显然这是一个不安全的优化,可能无法解决一大堆微妙的原因.我只是在尝试,而不是计划在生产代码中使用它.)

我使用属性[StructLayout(LayoutKind.Sequential,Pack = 1)]强制不填充并强制内存顺序匹配声明顺序.我用反射检查该属性,但实际上所有这些都证实是"无填充".我还需要字段的顺序.(我非常希望不必为每个字段手动指定FieldOffset属性,因为这样很容易出错.)

我假设我可以使用GetFields返回的字段顺序,但文档明确指出订单未指定.

鉴于我使用StructLayout属性强制字段的顺序,有没有办法反映该排序?

编辑我很好,所有字段必须是blittable的限制.

c# reflection serialization memory-layout bit-packing

10
推荐指数
1
解决办法
1383
查看次数

获取堆上对象的大小(以字节为单位)

我知道你可以MemoryLayout<T>.size用来获得一个类型的大小T.

例如: MemoryLayout<Int32>.size // 4

但是,对于类实例(对象),MemoryLayout<T>.size返回对象的引用大小(64位计算机上的8个字节),而不是堆上实际对象的大小.

class ClassA { // Objects should be at least 8 bytes
    let x: Int64 = 0
}

class ClassB  {// Objects should be at least 16 bytes
    let x: Int64 = 0
    let y: Int64 = 0
}

MemoryLayout<ClassA>.size // 8
MemoryLayout<ClassB>.size // 8, as well :(
Run Code Online (Sandbox Code Playgroud)

如何获得物体的大小?

对于那些想知道的人,我没有真正的需要,我只是在探索Swift及其与C的互操作性.

heap-memory memory-layout dynamic-allocation swift

10
推荐指数
2
解决办法
5043
查看次数

当基类不是多态而是派生时,'this'地址不匹配

有这个代码:

#include <iostream>

class Base
{
public:
    Base() {
        std::cout << "Base: " << this << std::endl;
    }
    int x;
    int y;
    int z;
};

class Derived : Base
{
public:
    Derived() {
        std::cout << "Derived: " << this << std::endl;
    }

    void fun(){}
};

int main() {
   Derived d;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Base: 0xbfdb81d4
Derived: 0xbfdb81d4
Run Code Online (Sandbox Code Playgroud)

但是,当Derived类中的函数'fun'更改为virtual时:

virtual void fun(){} // changed in Derived
Run Code Online (Sandbox Code Playgroud)

然后,'this'的地址在两个构造函数中都不相同:

Base: 0xbf93d6a4
Derived: 0xbf93d6a0
Run Code Online (Sandbox Code Playgroud)

另一件事是如果类Base是多态的,例如我添加了一些其他虚函数:

virtual void funOther(){} // added to Base
Run Code Online (Sandbox Code Playgroud)

那么'this'匹配的地址再次: …

c++ polymorphism inheritance memory-layout

9
推荐指数
2
解决办法
1803
查看次数

输入trait以标识主要基类

如果我有一个类Base,至少有一个虚函数,并且一个Derived类从中单独继承,(uintptr_t)derived - (uintptr_t)static_cast<Base*>(derived)则保证(由Itanium ABI)为零,即使Derived不是标准布局.然而,在一般情况下,这不一定是真的(例如,多重继承).

是否有可能编写一个特征,可用于检测一个类是否是另一个类的主要基类?

来自Itanium ABI的有用部分:

http://refspecs.linux-foundation.org/cxxabi-1.83.html

主要基类

对于动态类,它与偏移0共享虚拟指针的唯一基类(如果有).它是第一个(以直接基类顺序排列)非虚拟动态基类(如果存在).

动态类

需要虚拟表指针的类(因为它或其基数具有一个或多个虚拟成员函数或虚拟基类).

c++ memory-layout type-traits vptr itanium-abi

8
推荐指数
1
解决办法
1837
查看次数

如何禁止建造物体?

如何禁止构造物体?我将= delete;所有相关的特殊功能标记如下:

struct A
{
    A() = delete;
    A(A const &) = delete;
    A(A &&) = delete;
    void * operator new(std::size_t) = delete;
    void operator delete(void *) = delete;
};
A x{};
A y = {};
A * z = ::new A{};
Run Code Online (Sandbox Code Playgroud)

LIVE EXAMPLE

但是x,y*z仍然可以存在.该怎么办?我对这两种情况都感兴趣; 静态/堆栈分配和堆分配.

c++ memory-management memory-layout c++11 c++14

8
推荐指数
3
解决办法
334
查看次数

OCaml如何在运行时表示惰性值?

这一在现实世界中OCaml中描述了不同数据类型的运行时内存布局。但是,没有关于惰性值的讨论。

  • 如何lazy_t实现,即它的运行时表示形式是什么以及编译器内置的主要操作是什么?链接到源代码将不胜感激。我查看了CamlinternalLazy模块,但是仅基于对Obj模块中函数的调用,似乎很难解读实际的表示形式。
  • 有人可以提供对表示/操作所做的更改的摘要,以使其对于OCaml多核项目而言是线程安全的吗?这个提交似乎是实现的提交,但是对于我来说,作为局外人来说似乎有点不透明。

注意:此问题 OCaml编译器/运行时有关。据我所知,有如何偷懒值应该由没有实施标准规范 ocaml的编译器/运行。

ocaml lazy-evaluation memory-layout data-representation

8
推荐指数
1
解决办法
178
查看次数

为什么即使不涉及虚拟功能,虚拟继承也需要vtable?

我读了一个问题:C ++虚拟类继承对象大小问题,并且想知道为什么虚拟继承会在类中导致附加的vtable指针。

我在这里找到了一篇文章:https : //en.wikipedia.org/wiki/Virtual_inheritance

告诉我们:

但是,通常只能在运行时知道此偏移量,...

我在这里不了解与运行时相关的内容。完整的类继承层次结构在编译时就已经知道。我了解虚函数和基指针的用法,但是虚继承没有这种东西。

有人可以解释为什么某些编译器(Clang / GCC)使用vtable实现虚拟继承以及在运行时如何使用它吗?

顺便说一句,我也看到了这个问题:在虚拟继承的情况下使用vtable,但是它仅指向与虚拟函数相关的答案,这不是我的问题。

c++ virtual-inheritance vtable memory-layout vptr

8
推荐指数
2
解决办法
170
查看次数