gpt4 book ai didi

c++ - 保存和恢复内存位置列表的清洁机制?

转载 作者:行者123 更新时间:2023-11-28 06:49:13 24 4
gpt4 key购买 nike

我有一个内存位置列表,我需要作为一个组访问这些位置,偶尔也需要单独访问这些位置。我想提供一个单一的规范点。当前的设计很困惑,我想知道是否有人有解决这个问题的好方法(最好是 C++ 风格)。

我有一个巨大的潜在内存位置列表,每个产品将(在设计时)从中选择最多大约 100 个,或多或少平均分成两组。

在代码的某个点,我们将所有内存位置复制到一个缓冲区,然后偶尔从原始位置和存储的缓冲区中读回它们。经过一定时间后(大约 50,000 行代码之后),我们会将保存的数据恢复回内存。

当前代码(排序)

我们目前正在做的事情如下:

#define BLOCK_LIST_LOCATIONS1 = 0x1400, 0x1450
#define BLOCK_LIST_LOCATIONS2 = BLOCK_LIST_LOCATIONS1, 0x1000, 0x1002, 0x2040, 0xFFFF

union {

struct {
struct { // Must be kept in sync with BLOCK_LIST_LOCATIONS1
uint16_t Mem1400;
uint16_t Mem1450;
} List1;
uint16_t Mem1000; // Must be kept in sync with BLOCK_LIST_LOCATIONS2
uint16_t Mem1002;
uint16_t Mem2040;
} BlockList;

uint16_t BlockArray[sizeof(BlockList)/sizeof(uint16_t)];

} MemoryBlock;

uint32_t BASE_PTR = 0x30300000;


// block.cpp
uint16_t BlockMemoryLocationsArray[] = { BLOCK_LIST_LOCATIONS2 };

void SaveAwayMemory() {

for (int i = 0; BlockMemoryLocationsArray[i] < 0xFFFF; i++) {
MemoryBlock.BlockArray[i] = *(BASE_PTR + BlockMemoryLocationsArrary[i]);
}
}

void RestoreFromMemory(bool skipList1) {
int startingLocation = 0;

if (skipList1) startingLocation += sizeof(BlockList::List1) / sizeof(uint16_t);

for (int i = startingLocation; BlockMemoryLocationsArray[i] < 0xFFFF; i++) {
*(BASE_PTR + BlockMemoryLocationsArrary[i]) = MemoryBlock.BlockArray[i];
}
}

这带来了很多问题,因为保持多个列表同步很痛苦,而且这里的错误往往是相当讨厌的内存损坏问题。

一些奇怪的限制:我们没有堆,我们在使用 armcc 的嵌入式平台上运行。

是否有一个相对干净的替代实现可以给我

  • 单独访问每个保存的值
  • 轻松批量保存/恢复
  • 能够仅指定一次位置

高级代码使用

SaveAwayMemory();
// Literally thousands of lines of processing... including things like the following
Write1550(MemoryBlock.BlockList.List1.Mem1450 | 0x0020);

if (Read1000() != MemoryBlock.BlockList.Mem1000) // freak out if this changed

RestoreFromMemory(true);

最佳答案

这是我在餐巾背面画的。

template <int ... Values>
struct Bimap;

template <>
struct Bimap<>
{
static const int Size = 0;
};

template <int Value0, int ... Values>
struct Bimap<Value0, Values...>
{
static const int Val = Value0;
using Next = Bimap<Values...>;
static const int Size = 1 + Next::Size;
};

template<typename A, int I>
struct Get;

template<typename A>
struct Get<A, 0>
{
static const int Val = A::Val;
};

template<typename A, int I>
struct Get
{
static const int Val = Get<typename A::Next, I-1>::Val;
};

template<typename A, int Val>
struct Find;

template<int Value0, int... Values>
struct Find<Bimap<Value0, Values...>, Value0>
{
static const int Idx = 0;
};

template<int ValueToFind, int Value0, int... Values>
struct Find<Bimap<Value0, Values...>, ValueToFind>
{
static const int Idx = 1 + Find<Bimap<Values...>, ValueToFind>::Idx;
};

现在这与什么有什么关系?如果你有

using MyLocations = Bimap<0x1000, 0x1100, 0x1400, 0x1500>;

然后

Get<MyLocations, 3>::Val == 0x1500

Find<MyLocations, 0x1500>::Idx = 3

现在你可以声明

uint16_t MyBlocks[MyLocations::Size];

和使用

MyBlocks[Find<MyLocations, 0x1500>::Idx] = 
MyBlocks[Find<MyLocations, 0x1400>::Idx] | 0x777;

这大约相当于前者

MemoryBlock.BlockList.Mem1500 = MemoryBlock.BlockList.Mem1400 | 0x777;

我希望您可以根据自己的具体需求进行调整。

我几乎可以肯定 Boost 已经有了类似的东西,但我懒得去找它。

关于c++ - 保存和恢复内存位置列表的清洁机制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24321709/

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