![](/img/trans.png)
[英]Segmentation fault with dynamically allocated arrays as members of structure in c++?
[英]Control dynamically the number of members in c++ data structure
我目前正在编写一个处理数据库的程序。
我可以要求不同的选项并获得可变数量的列。
问题在于数据将是千兆字节的信息,而我无法用所有可能的选项来构建一种结构。 我需要能够动态创建仅包含我需要的成员而没有其他成员的结构。
我还希望有比为每种可能的情况创建结构更好的方法!
以下是表格示例:
smallint(6) - varchar(255) - double - int(11)
smallint(6) - varchar(255) - double - double - double - int(11)
smallint(6) - smallint(6) - varchar(255) - varchar(255) - double - int(11)
有什么方法可以创建具有动态成员数量的结构,而这种结构的成员数量与普通结构一样高效?
[编辑]
这是使用@ Industrial-antidepressant想法的解决方案。 它可以工作,但唯一的问题似乎比普通结构慢4倍。
#include <windows.h>
class Column
{
public:
Column(uint64 nOffset, const type_info* pType)
{
m_nOffset = nOffset;
m_pType = pType;
}
uint64 m_nOffset;
const type_info* m_pType;
};
struct UWElement
{
public:
template<class T>
void Set(uint64 nColumn, T value)
{
if ((*m_pColumnList)[nColumn].m_pType == &typeid(T))
{
uint64 nOffset = (*m_pColumnList)[nColumn].m_nOffset;
*(reinterpret_cast<T*>(m_pData + nOffset)) = value;
}
else
{
assert(0);
}
}
template<class T>
T& Get(uint64 nColumn)
{
// No type check here to test speed
uint64 nOffset = (*m_pColumnList)[nColumn].m_nOffset;
return *reinterpret_cast<T*>(m_pData + nOffset);
}
protected:
unsigned char* m_pData;
std::vector<Column>* m_pColumnList;
friend class UWElementList;
};
class UWElementList
{
public:
UWElementList()
{
m_nEndOffset = 0;
}
template<class T>
void AddType()
{
Column column(m_nEndOffset, &typeid(T));
m_columnlist.push_back(column);
m_nEndOffset += sizeof(T);
}
void CreateElement()
{
UWElement element;
element.m_pData = new unsigned char[m_nEndOffset];
element.m_pColumnList = &m_columnlist;
m_elementList.push_back(element);
}
UWElement& operator[](int64 nPos)
{
return m_elementList[nPos];
}
private:
std::vector<Column> m_columnlist;
uint64 m_nEndOffset;
std::vector<UWElement> m_elementList;
};
int main()
{
struct SimilarStruct
{
double a;
int b;
int c;
};
SimilarStruct similar;
vector<SimilarStruct> similarList;
similarList.push_back(similar);
UWElementList list;
list.AddType<double>();
list.AddType<int>();
list.AddType<int>();
list.CreateElement();
// Test writing speed
uint64 nTick = GetTickCount64();
for(int i=0; i<100*1000*1000; i++)
{
//list[0].Set<double>(0,(double)1.1); //Speed 140ms
list[0].Get<double>(0) = (double)1.1; //Speed 109ms
//similarList[0].a = (double)1.1; //Speed 31ms
}
cout << GetTickCount64() - nTick << endl;
double d=0;
// Test reading speed
nTick = GetTickCount64();
for(int i=0; i<100*1000*1000; i++)
{
d += list[0].Get<double>(0); //Speed 94ms
//d += similarList[0].a; //Speed 93ms
}
cout << GetTickCount64() - nTick;
return d;
}
是否有任何优化可以帮助加快速度?
如果您愿意使用Boost库,这里有一些想法。
您可以尝试使用boost::variant<list of possible types>
的二维数组。 对于动态二维数组,可以使用boost::multi_array
。
根据文档, boost::variant
具有:
高效的实现-尽可能基于堆栈(有关更多详细信息,请参见““永不空缺”保证”一节 )。
在表示数据库行之前,我已经成功使用了boost::variant
向量,但是我的内存需求比您的要适度得多。 您可能必须对这种方法进行基准测试,以查看它是否可行。
如果使用这种方法,则可能需要某种方式在运行时确定给定数据库列的索引。 如果要按名称访问列,则可以使用std::map
或boost::unordered_map
在列名称和列索引之间进行映射。
希望这可以帮助。
如何使用链接列表。 您可以使用new运算符动态分配内存给每个节点。
该性能可能不等于使用预定义结构时所获得的性能,但是它提供了更多的控制权。
如果仍然只想创建动态结构,则可以在结构内部使用并集。
更多信息: C ++中的动态结构
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.