考虑以下:
// Just a sequence of adjacent fields of same the type
#[repr(C)]
#[derive(Debug)]
struct S<T> {
a : T,
b : T,
c : T,
d : T,
}
impl<T : Sized> S<T> {
fn new(a : T, b : T, c : T, d : T) -> Self {
Self {
a,
b,
c,
d,
}
}
// reinterpret it as an array
fn as_slice(&self) -> &[T] {
unsafe { std::slice::from_raw_parts(self as *const Self as *const T, 4) …Run Code Online (Sandbox Code Playgroud) 最近我一直在尝试为一个老游戏制作一个插件,并遇到了类似于钻石继承的问题。
我有一个非常精简的例子,写如下:
#include <iostream>
#include <stdint.h>
#include <stddef.h>
using namespace std;
struct CBaseEntity
{
virtual void Spawn() = 0;
virtual void Think() = 0;
int64_t m_ivar{};
};
struct CBaseWeapon : virtual public CBaseEntity
{
virtual void ItemPostFrame() = 0;
double m_flvar{};
};
struct Prefab : virtual public CBaseEntity
{
void Spawn() override { cout << "Prefab::Spawn\n"; }
void Think() override { cout << "Prefab::Think\n"; }
};
struct WeaponPrefab : virtual public CBaseWeapon, virtual public Prefab
{
void Spawn() override { …Run Code Online (Sandbox Code Playgroud) 我知道这个答案违反了reinterpret_cast规则,但它也假设子阵列将被线性分配.
我相信这不能保证,但是当我搜索标准时,我发现我的信心摇摆不定.如果我静态分配2D数组,如下所示:
int foo[][4] = { { 5, 7, 8 },
{ 6, 6 },
{},
{ 5, 6, 8, 9 } };
Run Code Online (Sandbox Code Playgroud)
我可以假设所有元素都将线性分配吗?也就是说,如果foo[0]是在地址0x00000042,将:
foo[1] 在地址0x00000052foo[2] 在地址0x00000062foo[3] 在地址0x00000072这些地址是十六进制的,是的,它们为4元素子阵列提供了空间sizeof(int) == 4; 它们可能也可能不是零初始化.
我正在调试MPlayer-1.3.0源代码,我看到一个全局变量,其地址(由GDB简单打印返回或甚至简单打印)都在堆分配的范围内,而不是数据部分.我使用了检查堆范围procfs.
555555554000-555555834000 r-xp 00000000 08:12 798876 /usr/bin/mplayer
555555a33000-555555b25000 r--p 002df000 08:12 798876 /usr/bin/mplayer
555555b25000-555555b2b000 rw-p 003d1000 08:12 798876 /usr/bin/mplayer
555555b2b000-555556479000 rw-p 00000000 00:00 0 [heap]
7fffc3fff000-7fffc8000000 rw-s 00000000 00:16 1932 /dev/shm/pulse-shm-3887887751
Run Code Online (Sandbox Code Playgroud)
变量的定义是int verbose = 0;,在line 40的mp_msg.c和地址是0x555555b3bbb0,这是在[heap]映射.我甚至在它之前和之后检查了一些变量定义:
int mp_msg_levels[MSGT_MAX]; // verbose level of this module. initialized to -2
int mp_msg_level_all = MSGL_STATUS;
int verbose = 0;
int mp_msg_color = 0;
int mp_msg_module = 0;
Run Code Online (Sandbox Code Playgroud)
其中,仅 …
对不起,如果我的怀疑太幼稚。但我有一个类型转换难度std::atomic要char*类型。是强制转换std::atomic to char有效吗?
我可以写这样的类型转换变量。我确信当线程试图将变量写入变量时不会有多线程读/写操作(我知道,当该变量没有并发访问时,就不需要使用原子)。
std::atomic<uint8_t>* data_;
char *data = reinterpret_cast<char*>(data_);
*data |= mask;
Run Code Online (Sandbox Code Playgroud)
安全吗?
编辑:我不确定是否值得一提。在我的代码中
char *raw;
// variable raw is allocated
std::atomic<uint8_t>* data_ = reinterpret_cast<std::atomic<uint8_t>*>(raw);
Run Code Online (Sandbox Code Playgroud)
上面是std::atomic< uint8_t>创建方法的方式(作为char和type强制转换为std :: atomic类型)。
谢谢 :)
是否可以在 numpy 中创建一个不是 C_CONTIGUOUS 或 F_CONTIGUOUS 的一维数组?
我认为连续的概念只对具有更多维度的数组有意义,但我在文档中找不到任何内容。
我尝试了以下方法来制作不连续的一维数组:
>>> np.empty(10).flags
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
>>> np.empty(10).copy('F').flags
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
Run Code Online (Sandbox Code Playgroud) #include <iostream>
using namespace std;
class A {
int a;
};
class B1 : virtual public A {
int b1;
};
class B2 : virtual public A {
int b2;
};
class C : public B1, public B2 {
int c;
};
int main() {
A obj1; B1 obj2; B2 obj3; C obj4;
cout << sizeof(obj1) << endl;
cout << sizeof(obj2) << endl;
cout << sizeof(obj3) << endl;
cout << sizeof(obj4) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
4
16
16 …Run Code Online (Sandbox Code Playgroud) 据我了解,所有成员函数在类定义时都将在单独的内存中创建,并且对所有对象都是通用的。并且只为每个对象单独创建成员变量。但是使用对象调用时成员函数是如何执行的呢?
这些成员函数的地址将存储在哪里?
class B{
public:
int a;
void fun(){
}
};
int main(){
B b;
std::cout<<sizeof(b)<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如果我执行这个程序,我得到的输出为 4(仅用于成员变量)。但是调用 b.fun() 正确调用了它的成员函数。它如何在不将其地址存储在对象中的情况下进行调用?成员函数地址存储在哪里?
是否有类似类内存布局的东西将存储这些地址?
我正在尝试使用指向另一个 var 的指针来操纵一个 var 的值的指针,这基于本地 vars 通常如何在 C 程序中堆叠。
int i = 30;
int arr[4];
printf("%d\n", *(arr - 5)); // 30
Run Code Online (Sandbox Code Playgroud)
int arr[4];
int i = 30;
printf("%d\n", *(arr - 5)); // also 30
Run Code Online (Sandbox Code Playgroud)
我认为后者应该打印 30 for *(arr + 5),因为这就是我认为本地变量被推入堆栈的方式,但变量似乎以相同的方式在内存中布置。我想了解这里发生了什么。另外,我假设这是依赖于系统/编译器的。
struct A {
var a:Int = 2
func f()->Int {
return 2*a
}
}
var obj = A()
obj.f()
Run Code Online (Sandbox Code Playgroud)
大小obj为8字节。如果我添加新属性,大小将会改变。没关系。
我想知道编译器如何关心函数的内存。无论struct中有没有func,大小都是一样的。但 func 也是信息,我想它也应该占用内存(也许我错了)。那么这个过程是如何进行的呢?
如果您推荐我主题名称以便我可以阅读,我将不胜感激。
谢谢