请考虑以下实现非常简单的环形缓冲区的C结构:
struct shm_buffer_s {
pthread_mutex_t shm_mutex;
uint16_t head;
uint16_t tail;
struct shm_node_s node[SHM_NODES_MAX];
};
然后我有一个将新数据集推入缓冲区的功能:
uint32_t PushDataset(const struct shm_dataset_s *dataset, struct shm_buffer_s *const input_buf)
{
uint32_t return_value = MEM_MGMT_SHM_ERROR;
uint16_t head_index = 0;
size_t payload_size = 0;
if((dataset == NULL) || (input_buf == NULL)){
return_value = MEM_MGMT_SHM_NULL_ERROR;
}
else if(pthread_mutex_lock(&input_buf->shm_mutex) != 0){
return_value = MEM_MGMT_SHM_MUTEX_ERROR;
}
else{
head_index = input_buf->head;
/* ...Rest of the function... */
}
return return_value;
}/*PushDataset*/
静态分析将head
的取消引用标记为潜在的越界错误。整个程序运行正常,该函数的调用者正确地为input_buf
保留了内存,并且在“ Pop”版本中,我没有得到类似这样的错误:
SI_32 PopDataset(struct shm_dataset_s *const dataset, struct shm_buffer_s *const output_buf)
{
SI_32 return_value = MEM_MGMT_SHM_ERROR;
UI_16 tail_index = 0;
size_t payload_size = 0;
if((dataset == NULL) || (output_buf == NULL)){
return_value = MEM_MGMT_SHM_NULL_ERROR;
}
else if(pthread_mutex_lock(&output_buf->shm_mutex) != 0){
return_value = MEM_MGMT_SHM_MUTEX_ERROR;
}
else{
/* Clear output dataset in case it wasn't initialized */
memset(dataset, 0, sizeof(struct shm_dataset_s));
tail_index = output_buf->tail;
/* ...Rest of the function... */
return return_value;
}/*PopDataset*/
struct shm_buffer_s *
指向的存储区域是由函数调用者创建的共享存储区域。