通过阅读这篇文章,很明显c ++中的放置新闻用于在预先分配的内存位置上调用类构造函数.
在内存已经初始化的情况下,是新的贴图还是reinterpret_cast更合适?
例如,假设我读取了一个原始字节流,表示来自TCP套接字的成帧消息.我把这个流放入一个framesync并检索一个代表我的类的已知大小的缓冲区,我称之为Message.我知道有两种方法可以继续.
创建一个带有标志的构造函数,告诉类不要初始化.通过"不初始化"标志在缓冲区上执行new放置.
Message::Message( bool initialize )
{
//
// Initialize if requested
//
if( initialize )
{
Reset( );
}
}
void Message::Reset( void )
{
m_member1 = 1;
m_member2 = 2;
}
Message* message = new ( buffer ) Message( false );
Run Code Online (Sandbox Code Playgroud)使用reinterpret_cast
Message* message = reinterpret_cast< Message* > ( buffer );
Run Code Online (Sandbox Code Playgroud)我相信这两者都会产生相同的结果.一个优先于另一个是更正确,更OO,更安全,更容易阅读或更好的风格?
我遇到了一些代码如下.
char *buffer = new char[sizeof(PoolThread) * numThreads];
m_threads = reinterpret_cast<PoolThread*>(buffer);
for (int i = 0; i < numThreads; i++)
{
new (buffer)PoolThread(*this);
buffer += sizeof(PoolThread);
}
Run Code Online (Sandbox Code Playgroud)
我想new这里是用于初始化指向m_threads真实对象(PoolThread类)的空内存空间
我用谷歌搜索,但只找到这样的用法信息new:
pointer = new somthing[number];
Run Code Online (Sandbox Code Playgroud)
我希望new在我的上层代码示例中使用更多信息.这种用法是否来自c ++标准?
所以考虑到这个c结构:
typedef struct {
int* arr1;
int* arr2;
} myStruct;
Run Code Online (Sandbox Code Playgroud)
这个答案描述了使用单个malloc来同时分配a myStruct和它的数组:
myStruct* p = malloc(sizeof(*p) + 10 * sizeof(*p->arr1) + 10 * num * sizeof(*p->arr2);
if(p != NULL) {
p->arr1 = (int*)(p + 1);
p->arr2 = p->arr1 + 10;
}
Run Code Online (Sandbox Code Playgroud)
我想知道有没有类似的方法来做到这一点new?
显然,我希望能够分配到我在运行时收到的大小,就像使用C示例一样.
我正在学习c ++,并想知道这样的程序是如何组织在主存储器中的.我知道有一个堆栈(带有堆栈框架)和一个堆.我知道动态分配的东西会在堆上分配它.这是由像malloc或的运营商完成的new.但我不能在这个小型的c ++程序中看到它们.
该程序由一个主类和一个名为的类组成MyClass.这堂课有:
int)main类定义了一个Myclass对象,并定义了一个指向该对象的指针.
那么 - 这一切如何在记忆中组织起来?
#include <iostream>
using namespace std;
class MyClass {
int i;
public:
MyClass(int n) {
i = n;
}
int get_nmbr() {
return this->i;
}
};
int main() {
MyClass myClass(100), *p;
cout << myClass.get_nmbr() << endl;
p = &myClass;
cout << p;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 基本上,我有一个纯虚拟类Base,以及一个继承自Base的具体类Derived.然后我分配一块内存并通过简单的转换将其视为Derived数组.然后,我使用=填充数组.最后,我循环遍历数组,尝试调用在Base中声明并在Derived中定义的虚方法GetIndex.
问题是我最终得到一个访问冲突异常试图读取指向vtable for Base的指针(在Visual Studio调试中,这显示为__vfptr,它始终是0xbaadf00d).
以下是我遇到的问题的一个简单示例:
#include "stdafx.h"
#include "windows.h"
struct Base
{
virtual int GetIndex() const = 0;
};
struct Derived : public Base
{
int index;
Derived()
{
static int test = 0;
index = test++;
}
int GetIndex() const
{
return index;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int count = 4;
// Also fails with malloc
Derived* pDerived = (Derived*)HeapAlloc(GetProcessHeap(), 0, sizeof(Derived) * count);
for (int i = 0; i < count; i++)
{ …Run Code Online (Sandbox Code Playgroud) 我们可以在堆之外的其他地方放置动态分配的对象吗?我将如何定义一个重载的新运算符?
如果我有一些类竞技场
class Arena{
char area[2000];
public:
Arena(){}
};
Run Code Online (Sandbox Code Playgroud)
Arena my_arena(1000);
我想从Arena my_arena分配对象..
此外,与在性能等上从堆分配相比,这种内存分配有哪些可能的缺点?
说我们有
Class A{};
int *p = malloc(100);
A a; //default constructor in use
*p = A; (question???)
Run Code Online (Sandbox Code Playgroud)
如何在alloc memory p上初始化类型A的对象?
我正在尝试用malloc和free替换operator new和delete(我有理由).问题显示在下面的代码中:
std::string *temp = (std::string *)malloc(sizeof(std::string) * 2); // allocate space for two string objects.
temp[0] = "hello!";
temp[1] = "world!";
for(int i = 0; i < 2; i++)
{
printf("%s\n", temp[i].c_str());
}
free(temp);
return 0; // causes SIGSEGV.
Run Code Online (Sandbox Code Playgroud)
然而..
std::string *temp = new std::string[2];
temp[0] = "hello!";
temp[1] = "world!";
for(int i = 0; i < 2; i++)
{
printf("%s\n", temp[i].c_str());
}
delete [] temp;
return 0; // works fine
Run Code Online (Sandbox Code Playgroud)
为什么?并且有人可以建议我用malloc和free替换这些运算符的正确方法是什么?
问候.
编辑:这只是一个例子,我没有使用标准的C++库.
编辑:这样的事情怎么样?
class myclass
{
public: …Run Code Online (Sandbox Code Playgroud) 我试图在这里找到答案,但我没有找到任何工作。我这里有一个二十一点游戏。我的下一步是开始在游戏中添加资金余额并下注,但在此之前,我正在研究我的“再玩”选项。就目前而言,当玩家再次玩时,他们的手牌与上一轮相同。我相信我需要调用析构函数来删除当前的手牌和套牌,然后重新开始。不幸的是,我无法弄清楚如何清除手并从新的甲板开始。我试图在名为 play 的函数中调用这个析构函数。在这里,如果玩家说他们想再玩一次,我会删除手牌和套牌,然后在主界面中重建它们。但是我已经尝试过“deck.Deck::~Deck()”和“deck.~Deck()”,但都没有奏效。我会上传我所有的代码。如果有人有任何想法,请帮助我。我知道析构函数应该在超出范围时由编译器调用,但是如何在游戏仍在运行且主要仍在运行的情况下从新的手牌和套牌开始?感谢您的帮助。
这是我的头文件:
//blackjack.h A class to represent a deck of cards
#include <iostream>
#include <string>
class Card {
friend class Deck;
private:
int card_index; //card number 0 to 51
Card(int index) { card_index = index; } //made this private so user can't say card at index 100..can use it because of friend class
public:
Card() { card_index = 52; }
char suit() const;
char value() const;
std::string str() const;
int getValue(std::string c);
};
class Deck {
private:
Card …Run Code Online (Sandbox Code Playgroud) Cppreference 指出,关于std::memcpy()(强调):
如果对象可能重叠或不可平凡复制,则 的行为
memcpy未指定并且可能未定义。
因此,我总是在使用之前检查以确保对象是可简单复制的memcpy(),如下所示:
#include <type_traits>
static_assert(std::is_trivially_copyable<T>::value, "Type T must "
"be a trivially-copyable type in order to guarantee that `memcpy()` is safe "
"to use on it.");
memcpy(&outputData, &data, sizeof(data));
Run Code Online (Sandbox Code Playgroud)
std::copy()然而,似乎没有这个限制:https://en.cppreference.com/w/cpp/algorithm/copy。
类型必须可简单复制才能不具有未定义行为的限制是否不适用于std::copy()?
另外,我刚刚在我的“placement new”答案中意识到,这让我想知道整个事情,我只是用了memcpy()代替std::memcpy(),而我没有, using namespace std;那么调用了哪个函数?是memcpy()与 不同的实现吗std::memcpy()?
析构函数的语法是~classname. 这导致需要在析构函数调用中显式写入对象的类型。为了避免这种情况,C++17 引入了std::destroy_at.
那么,Bjarne Stroustrup 选择~classname析构函数语法的最初理由是什么?如果语法不依赖于类型,std::destroy_at则不需要。
c++ ×12
memory ×3
destructor ×2
heap ×2
c ×1
dynamic ×1
inheritance ×1
keyword ×1
malloc ×1
memcpy ×1
new-operator ×1
stack ×1
vtable ×1