- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这是我的第一篇文章。我希望它包含正确的、最少的信息。如果我遗漏了什么,请告诉我。
我正在尝试使用 placement new 来提高以下代码块的效率(我想减少内存分配调用的次数,因为 number_of_actions
变量很大(> 500k)) .
首先,我使用了两个类,它们的关系可以概括为:
class txn {
public:
int i;
txn(): i(0) {};
};
class ActionClass {
private:
txn* t;
public:
ActionClass(txn* t): t(t) {};
~ActionClass() { delete t; }
};
我最初用来创建对象指针数组的代码:
std::vector<std::unique_ptr<IBatchAction>> allocate_actions(unsigned int number_of_actions) {
std::vector<std::unique_ptr<IBatchAction>> res;
for (unsigned int i = 0; i < number_of_actions; i++) {
// construct the action
std::unique_ptr<IBatchAction> act = std::make_unique<ActionClass>(new TestTxn());
res.push_back(std::move(act));
}
return res;
}
更改为使用 placement new 后的代码:
std::vector<std::unique_ptr<IBatchAction>> allocate_actions(unsigned int number_of_actions) {
std::vector<std::unique_ptr<IBatchAction>> res(number_of_actions);
// allocate all of the memory for actions up front to amortize the cost.
ActionClass* actions =
reinterpret_cast<ActionClass*>(new char[number_of_actions * sizeof(ActionClass)]);
txn* txns = reinterpret_cast<txn*>(new char[number_of_actions * sizeof(TestTxn)]);
// use placement new to initialize actions and assign them to unique_ptrs
for (unsigned int i = 0; i < number_of_actions; i++) {
// construct the action using placement new from the memory allocated above.
res[i].reset(new(&(actions[i])) ActionClass(new(&(txns[i])) TestTxn()));
}
return res;
}
在 main.cpp 中,我只是多次调用上述函数,计时并返回 0。从上述函数返回的 vector 在循环迭代之间被销毁。结果,我在段错误之前得到了以下堆栈跟踪:
#0 std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >::~unique_ptr (
this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/c++/5/bits/unique_ptr.h:236
#1 std::_Destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> > > (
__pointer=<optimized out>) at /usr/include/c++/5/bits/stl_construct.h:93
#2 std::_Destroy_aux<false>::__destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >*> (__last=<optimized out>, __first=0x7ffff7f06018)
at /usr/include/c++/5/bits/stl_construct.h:103
#3 std::_Destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >*> (
__last=<optimized out>, __first=<optimized out>) at /usr/include/c++/5/bits/stl_construct.h:126
#4 std::_Destroy<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >*, std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> > > (__last=0x7ffff7fc9510,
__first=<optimized out>) at /usr/include/c++/5/bits/stl_construct.h:151
#5 std::vector<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> >, std::allocator<std::unique_ptr<IBatchAction, std::default_delete<IBatchAction> > > >::~vector (this=0x7fffffffd910,
__in_chrg=<optimized out>) at /usr/include/c++/5/bits/stl_vector.h:424
#6 time_workload_creation (exp_conf=...) at start_batch/main.cc:18
#7 0x000000000040320c in main (argc=<optimized out>, argv=<optimized out>)
at start_batch/main.cc:44
我不熟悉展示位置的概念。以下是我用来编写上述代码的内容:
我可能做了一些明显错误的事情,但我无法弄清楚。帮助?如果您需要来自 main(简化)的实际代码,就在这里(actions.h 包含我已经讨论过的函数)。
#include "actions.h"
#include <chrono>
#include <vector>
void time_workload_creation(unsigned int act_num) {
std::chrono::system_clock::time_point time_start, time_end;
std::vector<double> results;
for (unsigned int i = 0; i < 10; i++) {
time_start = std::chrono::system_clock::now();
auto workload = allocate_actions(act_num);
time_end = std::chrono::system_clock::now();
results.push_back(
std::chrono::duration_cast<std::chrono::milliseconds>(time_end - time_start).count());
}
for (unsigned int i = 0; i < 10; i++) {
std::cout << i << "\t\t" <<
act_num << "\t\t" <<
results[i] << "\t\t" <<
act_num / results[i] << std::endl;
}
};
int main(int argc, char** argv) {
time_workload_creation(1000000);
return 0;
}
编译使用:gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
最佳答案
Code after changing to use placement new:
[...]
此代码具有未定义的行为。您使用 new[]
创建一个 char
数组,然后重置 N 个 unique_ptr
对象,这将尝试删除 N 个不同的 ActionClass
对象。你希望它如何工作?您需要使用 delete[]
来释放 char 数组,而不是对 char
数组的 block 使用 N delete
操作。
同样,每个 ActionClass
都会尝试delete
它的 txn
对象,但这也是完全未定义的,因为你没有分配 N txn
对象,你分配了另一个 char
数组。
这不是内存分配的工作方式。您不能先分配一大块,然后再释放其中的一部分。 (好吧,你可以,但只能通过编写你自己的自定义(取消)分配函数或分配器)。
关于c++ - 放置新的唯一指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43722222/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
指针, C语言的精髓 莫队先咕几天, 容我先讲完树剖 (因为后面树上的东西好多都要用树剖求 LCA). 什么是指针 保存变量地址的变量叫做指针. 这是大概的定义, 但是Defad认为
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我是一名优秀的程序员,十分优秀!