我正在使用 C++ 开发一个库来处理 CDROM 映像的扇区,删除一些数据并存储有关扇区类型的索引。出于测试目的,我正在读取大约 100 个扇区的块中的图像文件,并且我正在使用一些内存缓冲区作为临时存储在类函数中处理这些扇区。我的问题只是删除其中一个缓冲区,并且 delete[] 运算符以随机方式失败并出现 SIGTRAP 错误(并不总是同时发生)。
这部分代码很简单:
int8_t processor::cleanStream(
uint8_t *out,
uint64_t &outSize,
uint8_t *in,
uint64_t inSize,
uint32_t startSectorNumber,
optimizations &options,
sector_type *sectorsIndex,
uint32_t sectorsIndexSize,
bool useTheBestOptimizations)
{
...
uint32_t inputSectorsCount = inSize / 2352;
/* Analize the stream to generate an index, and if useTheBestOptimizations is enabled modify the optimizations options */
sector_type *index = new sector_type[inputSectorsCount]();
/* Create a buffer and try to encode the sectors one by one. If any of them cannot be recovered in a lossless way
detect the optimization which has caused the error and deactivate it */
uint8_t *buffer = new uint8_t[2352]();
uint32_t last_iterator = 0;
for (uint32_t i = 0; i < inputSectorsCount; i++)
{
/* Copy a sector into the buffer to work with it */
memccpy(buffer, in + (2352 * i), 2352, 2352);
/* Try to detect the sector type */
index[i] = detect(buffer);
if (useTheBestOptimizations)
{
/* Call the function which will determine if those optimizations are the best for that sector */
options = checkOptimizations(buffer, startSectorNumber + i, options, index[i]);
}
last_iterator = i;
}
/* Delete the buffer and reset the current position */
delete[] buffer;
/* Copy the detected index to the output and clear it */
memccpy(sectorsIndex, index, sectorsIndexSize, inputSectorsCount);
delete[] index;
...
}
使用调试器,我检查了内存区域状态,我能够看到初始化时如何清零,如何正确写入而不会写入保留区域(恰好 100 字节)。数据也毫无问题地复制到 sectorsIndex 内存区域,使用相同的运算符毫无问题地删除了“缓冲区”变量,甚至 last_iterator 变量也确认只写入了 100 个字节。
考虑到上述情况,我不知道如何面对这个问题,因为我的代码没有发现任何错误。该变量已正确初始化并在几行后被释放,因此没有错误的原因。它也不是 SEGFAULT,所以即使不检查内存区域,我也很确定我没有写错地方。我可能看到的唯一“原因”是保留内存没有以零结尾,也许 delete[] 没有以正确的方式管理它,但我认为它只对 char 数组很重要(并且在缓冲区数组不会发生)。
在确定检查代码后,我将删除这个“索引”缓冲区以直接写入 sectorsIndex 缓冲区,我将尝试更新我的代码以使用更多“unique_ptr”,但我想了解我是什么做错事是为了以后避免。
注意:sector_type 是一个 uint8_t 枚举:
enum sector_type : uint8_t
{
ST_UNKNOWN = 0,
ST_CDDA,
ST_CDDA_GAP,
ST_MODE1,
ST_MODE1_GAP,
ST_MODE1_RAW,
ST_MODE2,
ST_MODE2_GAP,
ST_MODE2_1,
ST_MODE2_1_GAP,
ST_MODE2_2,
ST_MODE2_2_GAP,
ST_MODEX
};