gpt4 book ai didi

c++ - static_cast 是否会使编译器分配比 new 运算符所指的空间更多的空间?

转载 作者:行者123 更新时间:2023-12-02 07:06:59 29 4
gpt4 key购买 nike

我编写了一个类和一个派生类,其中包含各自的数据成员,如下面的代码所示。现在,在 main 函数中,我使用 static_cast 创建了由 派生 类指针指向的新 Base 类对象。

#include <iostream>
#include <vector>
class Base {
public:
int b;
Base() : b(2){};
int get_b() const;
};

class Derived : public Base {
public:
int d;
Derived() : d(4){};
int get_d() const;
};

int Base::get_b() const { return b; }

int Derived::get_d() const { return d; }

int main() {
std::vector<Derived *> bArray;
bArray.push_back(static_cast<const Derived *>(new Base()));
bArray.push_back(static_cast<const Derived *>(new Base()));

std::vector<Derived *>::iterator bArrayIt = bArray.begin();
for (; bArrayIt != bArray.end(); ++bArrayIt) {
std::cout << (*bArrayIt)->get_b() << std::endl;
std::cout << (*bArrayIt)->get_d() << std::endl;
}
}

输出:

2
0

现在,在代码中,我尝试使用派生指针访问派生类的数据成员,但我希望它返回编译错误或“ArrayOutOfBoundIndex”或Segmentation_fault 因为该对象属于 Base 类型,因为空间仅为基础对象分配,但该成员“d”的值为零。根据我对static_cast的了解,它只是改变指针类型而不分配内存,但这里我们不仅可以访问未分配的内存,而且该值已预先设置为0,所以我这样做了我自己的一个小实验。

#include <iostream>
#include <string.h>

class State;
class Base;
class Derived;
class State {
public:
static bool flag;
};
bool State::flag = true;

class Base : public State {
public:
int a;
int b;
int c;
Base() : a(2), b(4), c(16){};

int get_a() { return a; }
int get_b() { return b; }
int get_c() { return c; }
};
class Derived : public Base {
public:
int d;
int e;
int f;
Derived() : d(6), e(8), f(12){};
int set_d(int ds) { d = ds; }
int get_d() { return d; }

int get_e() { return e; }
int get_f() { return f; }
};

int main() {
Derived *d[2];

d[0] = static_cast<Derived *>(new Base());
d[1] = static_cast<Derived *>(new Base());

std::cout << d[0]->get_a() << std::endl;
std::cout << d[0]->get_d() << std::endl;
d[0]->set_d(100);
std::cout << d[0]->get_d() << std::endl;
int *i = reinterpret_cast<int *>(d[0]);
std::cout << (*i) << std::endl;
i++;
std::cout << (*i) << std::endl;

i++;
std::cout << (*i) << std::endl;

i++;
std::cout << (*i) << std::endl;

i++;
std::cout << (*i) << std::endl;

i++;
std::cout << (*i) << std::endl;

std::cout << "Let's move onto d[1]" << std::endl;
int *j = reinterpret_cast<int *>(d[1]);
std::cout << (*j) << std::endl;
j++;

std::cout << (*j) << std::endl;
j++;

std::cout << (*j) << std::endl;
j++;

std::cout << (*j) << std::endl;

j++;
std::cout << (*j) << std::endl;
j++;

std::cout << (*j) << std::endl;
return 0;
}

输出:

2
0
100
2
4
16
100
0
0
Let's move into d[1]
2
4
16
0
0
0

输出是根据我之前得到的。

我的问题:

  1. 为什么允许变量访问不是由 new 关键字或编译器分配的内存?它是如何做到这一点的?
  2. 如果能够访问内存位置,为什么编译器不会给出任何运行时错误或编译时错误?是否有任何方法可以让编译器这样做?
  3. 现在,如果内存是由编译器或以某种方式分配的,那么它对内存有什么影响,即如果基类是 12 字节,派生类是 24 字节,那么每个基类的对象创建并使用派生指针指向的 static_cast 会分配 24 字节内存吗?

最佳答案

  1. Why is the variable allowed to access memory which is not allocated by the new keyword or the compiler and how is it able to do so?

因为,没有什么可以阻止你这样做。 C++ 为程序员提供了很大的自由,但这种自由也带来了责任(例如,确保不访问未分配的内存)。

  1. If it is able to access memory location why doesn't the compiler give any runtime error or compile time error?

这是未定义的行为,这意味着在运行时您的程序变得不可预测。如果你幸运的话,它可能会因某种原因崩溃(例如段错误),但并非必须如此。在编译时,此操作在语言方面是完全合法的,因此编译器不会提示。您可能需要使用一些静态分析工具来捕获此类错误。

  1. Now if the memory is allocated by the compiler or somehow, what implications does it have on the memory i.e. if the Base class is of 12 bytes and the Derived class is of 24 bytes then will every object creation of Base Type and using static_cast for it to be pointed by Derived pointer will allocate 24 bytes of memory?

static_cast 与内存分配无关。它只是转换指针的类型。为对象分配内存由operator new决定,分配的内存大小不会受到任何指针转换的影响。

关于c++ - static_cast 是否会使编译器分配比 new 运算符所指的空间更多的空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59307902/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com