Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法在AVR/Arduino微控制器中处理堆内存碎片?_Arduino_Microcontroller_Avr_Avr Gcc_Atmel - Fatal编程技术网

有没有办法在AVR/Arduino微控制器中处理堆内存碎片?

有没有办法在AVR/Arduino微控制器中处理堆内存碎片?,arduino,microcontroller,avr,avr-gcc,atmel,Arduino,Microcontroller,Avr,Avr Gcc,Atmel,我已经找了几天了,一点运气都没有 堆内存碎片是在微控制器/Arduino中大量使用malloc()和free()的结果 如果不可避免地要使用它们,我如何时不时地对堆进行碎片整理,以确保下一个malloc()调用将找到要分配的连续内存 创建一个固定大小的内存块池。当您需要任意数量的内存时,从池中分配一个块并使用您需要的部分。完成后,将块返回到池中。池永远不会碎片化,因为块的大小总是相同的。如果有任何块可用,那么它们的大小总是正确的。有时候你只需要几个字节,有一秒钟你会认为你把整个chunck都绑起

我已经找了几天了,一点运气都没有

堆内存碎片是在微控制器/Arduino中大量使用malloc()和free()的结果


如果不可避免地要使用它们,我如何时不时地对堆进行碎片整理,以确保下一个malloc()调用将找到要分配的连续内存

创建一个固定大小的内存块池。当您需要任意数量的内存时,从池中分配一个块并使用您需要的部分。完成后,将块返回到池中。池永远不会碎片化,因为块的大小总是相同的。如果有任何块可用,那么它们的大小总是正确的。有时候你只需要几个字节,有一秒钟你会认为你把整个chunck都绑起来是浪费。但是你会记得你正在避免内存碎片,你会感觉更好

如果分配的大小差异很大,那么一个固定大小的内存池可能真的太浪费了。然后,您可以为小型、中型和大型块创建两个或三个固定大小的内存池。但请确保将块返回到从中获取它们的池中


使用队列或链表来组织池中的块。分配块时,将从队列/列表中删除这些块。当它们被释放时,它们会返回到队列/列表。

正如@kkrambo提到的,使用队列或链接列表来跟踪分配的内存块。我特别为Arduino提供了一个示例,它没有我想要的所有铃声和口哨。 我选择只保留指向队列中内存块的指针,而不是内存块本身(这似乎是kkrambo所说的,尽管我不知道他/她是否是指我上面所说的。)

const int MAX_POOL_SIZE=4;
const int MAX_DATA_SIZE=128;
//数据存储池
队列阵列数据池;
void initDataPool(){
uint8_t*ptr;
对于(int i=0;i
但如果不可避免地要使用malloc(),有没有办法对内存进行碎片整理?重置设备并重新初始化堆将对内存进行碎片整理。可能在malloc()失败时重置,或者定期重置,或者在应用程序处于方便的状态时重置。但这与对内存进行碎片整理不同,这将丢弃所有分配的数据。您可以修改malloc,使其返回块的句柄,然后有一个函数,在每次需要访问块时将句柄转换为实际指针。通过这种方式,你可以滚动你自己的碎片整理,定期重新排列内存并更新句柄表。有趣的是,你有一个示例代码,或者你能告诉我这个方向吗?
const int MAX_POOL_SIZE = 4;
const int MAX_DATA_SIZE = 128;

// Memory pool for data
QueueArray <uint8_t*> dataPool;

void initDataPool () {
  uint8_t * ptr;
  for (int i = 0; i < MAX_POOL_SIZE; i++) {
    ptr = (uint8_t*) malloc(MAX_DATA_SIZE);     // Allocate MAX_DATA_SIZE buffer
    dataPool.push(ptr);                         // Push buffer pointer to queue
  }
}

// Allocate message data buffer from data pool
// If data pool still has buffer space available, and requested
// buffer size is suitable, return pointer to avalable buffer
static void* allocateDataBuff (size_t buffSize) {
  if (!dataPool.isEmpty()) {
    if (buffSize < MAX_DATA_SIZE) return dataPool.pop();
    else {
      if (debugMsg) Serial.println("allocateDataBuff: Requested Buffer Size is too large");
      return NULL;
    }
  } // if message pool still has buffer space available
  else {
    if (debugMsg) Serial.println("allocateDataBuff: Memory pool is full, no buffers available at this time");  
  }
}
void setup() {
    initDataPool();
}
void loop() {
    // ........
    uint8_t* dataPtr = (uint8_t*) allocateDataBuff(100);
    // ....assign message to *dataPtr
    // ........
    deallocateDataBuff(dataPtr);
}