前言
主要是對代碼進行了優化,優化的點有下面幾項
1 對代碼結構進行了調整。
上次的版本只是一個簡單的雛形,這份代碼進一步分成了頭文件和實現文件。
2 優化了類的封裝性,對具體實現進行了隱藏。
因為這個功能是通過頭結點的鏈表的實現的,而在上分代碼中,使用者可以通過調用的到頭結點信息,然后使用者就可以對這個鏈表進行任意操作,這樣就很危險。所以在這版中,將所有入口都改成了void *數據類型,在實現的地方進行類型轉換,增加了安全性。
具體實現
頭文件
#include
#include
#include
#include
#include
/*
* MemLink Brief Description
*
* link0
* addr(id, sum, size)->node->node->node->node...
*
* link1
* addr(id, sum, size)->node->node->node->node...
*
* link2
* addr(id, sum, size)->node->node->node->node...
*
*/
class MemLink
{
public:
MemLink() { m_mem_link.clear(); }
~MemLink() {}
//create link by id
int create_link(int id);
//get link addr, for first para is *addr, !!need to traverse!!
void *get_addr_by_id(int id);
//get link addr, for first para is *addr
void *get_addr_by_index(int index);
int push_data(void *addr, char *data, int len);
int read_data(void *addr, char *data, int len);
int pop_data(void *addr, char *data, int len);
//delete one link
int delete_link(void *addr);
//delete all links
int delete_memlink();
//get link description
int get_id_by_addr(void *addr);
int get_size_by_addr(void *addr);
int get_num_by_addr(void *addr);
int get_memlink_num();
void printf_memlink_status();
void link_test();
private:
std::vector<void *> m_mem_link;
void *mk_node(int id, char *data, int len);
int free_node(void *node);
int push(void *addr, void *node);
void *pop(void *addr);
void printf_link(void *addr); //debug, when data is ascii, can call it
};
實現文件
#include "test_mem_link.h"
typedef struct Node
{
int id; //unique id
int pos; //data start pos
int size; //data size --> value size = size-pos
int num; //for head only
char *data;
struct Node *next;
} Node;
void *MemLink::mk_node(int id, char *data, int len)
{
Node *node = new Node;
if (node == NULL) {
perror("new Node failed\\n");
return NULL;
}
if (data != NULL) {
node->data = new char[len]();
if (node->data == NULL) {
perror("node->data = new failed");
return NULL;
}
memcpy(node->data, data, len);
}
else node->data = NULL;
node->id = id;
node->pos = 0;
node->size = len;
node->num = 0;
node->next = NULL;
return (void *)node;
}
int MemLink::free_node(void *addr)
{
Node *node = (Node *)addr;
if (node->data != NULL)
delete[] node->data;
node->data = NULL;
if (node)
delete node;
node = NULL;
return 0;
}
void *MemLink::get_addr_by_id(int id)
{
int i = 0;
for (i = 0; i < (int)m_mem_link.size(); i++) {
if (id == ((Node *)m_mem_link[i])->id) {
return (Node *)m_mem_link[i];
}
}
return NULL;
}
int MemLink::create_link(int id)
{
Node *node_ret = (Node *)get_addr_by_id(id);
if (node_ret != NULL) {
printf("link id[%d] exist, can't create it\\n", id);
return -1;
}
printf("link id[%d] not exist, create it\\n", id);
Node *node = (Node *)mk_node(id, NULL, 0);
if (node == NULL) {
printf("mk_node failed!\\n");
}
else {
m_mem_link.push_back((void *)node);
}
return 0;
}
int MemLink::push(void *addr, void *node)
{
Node *p = (Node *)addr;
while (p->next != NULL) {
p = p->next;
}
((Node *)node)->next = p->next;
p->next = ((Node *)node);
((Node *)addr)->size += ((Node *)node)->size;
((Node *)addr)->num++;
return 0;
}
int MemLink::get_id_by_addr(void *addr)
{
return ((Node *)addr)->id;
}
int MemLink::get_size_by_addr(void *addr)
{
return ((Node *)addr)->size;
}
int MemLink::get_num_by_addr(void *addr)
{
return ((Node *)addr)->num;
}
int MemLink::push_data(void *addr, char *data, int len)
{
int id = get_id_by_addr(addr);
Node *phead = (Node *)addr;
Node *node = (Node *)mk_node(id, data, len);
if (node == NULL) {
printf("mk_node failed!\\n");
}
push(phead, node);
}
void *MemLink::pop(void *addr)
{
Node *p = ((Node *)addr)->next;
if (p != NULL) {
((Node *)addr)->size -= p->size - p->pos;
((Node *)addr)->next = p->next;
((Node *)addr)->num--;
p->next = NULL;
return p;
}
return NULL;
}
void *MemLink::get_addr_by_index(int index)
{
return m_mem_link[index];
}
int MemLink::read_data(void *addr, char *data, int len)
{
Node *phead = (Node *)addr;
if (len > phead->size) {
printf("pop data len > link size, read data failed\\n");
return -1;
}
int i_read = 0;
Node *p = phead->next;
while (1) {
if (p == NULL) {
printf("p == NULL\\n");
break;
}
if (i_read + p->size - p->pos > len) {
//printf(" < len\\n");
memcpy(&data[i_read], &p->data[p->pos], len - i_read);
break;
}
if (i_read + p->size - p->pos == len) {
//printf(" = len\\n");
memcpy(&data[i_read], &p->data[p->pos], p->size - p->pos);
break;
}
if (i_read + p->size - p->pos < len) {
//printf(" > len\\n");
memcpy(&data[i_read], &p->data[p->pos], p->size - p->pos);
i_read += p->size - p->pos;
p = p->next;
}
}
return 0;
}
int MemLink::pop_data(void *addr, char *data, int len)
{
Node *phead = (Node *)addr;
if (len > phead->size) {
printf("pop data len > link size, read data failed\\n");
return -1;
}
Node *phead_tmp = phead;
int i_read = 0;
while (1) {
Node *p = phead_tmp->next;
if (p == NULL) {
printf("p == NULL\\n");
break;
}
if (i_read + p->size - p->pos > len) {
// printf(" > len\\n");
memcpy(&data[i_read], &p->data[p->pos], len - i_read);
p->pos += len - i_read;
phead->size -= len - i_read;
break;
}
if (i_read + p->size - p->pos == len) {
// printf(" = len\\n");
memcpy(&data[i_read], &p->data[p->pos], p->size - p->pos);
phead->size -= p->size - p->pos;
phead_tmp->next = p->next;
phead->num--;
free_node(p);
p = NULL;
break;
}
if (i_read + p->size - p->pos < len) {
// printf(" < len\\n");
memcpy(&data[i_read], &p->data[p->pos], p->size - p->pos);
i_read += p->size - p->pos;
phead->size -= p->size - p->pos;
phead_tmp->next = p->next;
phead->num--;
free_node(p);
p = NULL;
}
}
return 0;
}
int MemLink::get_memlink_num()
{
return m_mem_link.size();
}
void MemLink::printf_memlink_status()
{
int i = 0;
for (i = 0; i < (int)m_mem_link.size(); i++) {
Node *phead = (Node *)m_mem_link[i];
printf(">link: id: %d, pos: %d, num: %d, size: %d, data: %s\\n", phead->id,
phead->pos, phead->num, phead->size, phead->data);
}
}
void MemLink::printf_link(void *addr)
{
Node *phead = (Node *)addr;
printf(">link: id: %d, pos: %d, num: %d, size: %d, data: %s\\n", phead->id,
phead->pos, phead->num, phead->size, phead->data);
Node *p = phead->next;
while (p) {
printf("node: id: %d, pos: %d, size: %d\\n", p->id, p->pos, p->size);
p = p->next;
}
}
int MemLink::delete_link(void *addr)
{
int id = get_id_by_addr(addr);
Node *phead = (Node *)addr;
Node *p = phead->next;
while (phead->next) {
p = phead->next;
phead->next = p->next;
free_node(p);
}
std::vector<void *>::iterator it;
for (it = m_mem_link.begin(); it != m_mem_link.end(); ) {
//if (((Node *)it)->id == get_id_by_addr(addr)))
if (*it == addr) {
//printf("%d = %d\\n", get_id_by_addr(*it), get_id_by_addr(addr));
it = m_mem_link.erase(it);
break;
}
else it++;
}
free_node(phead);
printf("delete id[%d] link\\n", id);
return 0;
}
int MemLink::delete_memlink()
{
int i = 0;
for (i = 0; i < (int)m_mem_link.size(); i++) {
int id = get_id_by_addr(m_mem_link[i]);
Node *phead = (Node *)m_mem_link[i];
Node *p = phead->next;
while (phead->next) {
p = phead->next;
phead->next = p->next;
free_node(p);
}
printf("delete id[%d] link\\n", id);
free_node(phead);
}
m_mem_link.clear();
return 0;
}
void MemLink::link_test()
{
int id = 10;
create_link(id);
// push
char tmp[10] = {0};
void *addr = get_addr_by_id(id);
strcpy(tmp, "111222333");
push_data(addr, tmp, strlen(tmp));
strcpy(tmp, "444555666");
push_data(addr, tmp, strlen(tmp));
strcpy(tmp, "777888999");
push_data(addr, tmp, strlen(tmp));
push_data(addr, (char *)"1", strlen("1"));
push_data(addr, (char *)"2", strlen("2"));
push_data(addr, (char *)"3", strlen("3"));
push_data(addr, (char *)"4", strlen("4"));
push_data(addr, (char *)"5", strlen("5"));
push_data(addr, (char *)"6", strlen("6"));
push_data(addr, (char *)"7", strlen("7"));
id = 20;
create_link(id);
addr = get_addr_by_id(id);
push_data(addr, (char *)"8", strlen("8"));
push_data(addr, (char *)"9", strlen("9"));
push_data(addr, (char *)"10", strlen("10"));
id = 30;
create_link(id);
addr = get_addr_by_id(id);
push_data(addr, (char *)"11", strlen("11"));
push_data(addr, (char *)"12", strlen("12"));
push_data(addr, (char *)"13", strlen("13"));
printf_memlink_status();
int memlink_num = get_memlink_num();
printf("\\nmemlink_num = %d\\n", memlink_num);
for (int i = 0; i < memlink_num; i++) {
void *addr = get_addr_by_index(i);
// printf_link(addr);
if (get_id_by_addr(addr) == 10) {
// //pop
// Node *p4 = pop(phead);
// printf("pop size = %d\\n", p4->size);
// free_node(p4);
char read_tmp[11 + 1] = {0};
pop_data(addr, read_tmp, 11);
printf("read_data = %s\\n", read_tmp);
char read_tmp2[8 + 1] = {0};
pop_data(addr, read_tmp2, 8);
printf("read_data = %s\\n", read_tmp2);
// printf_link(addr);
}
}
addr = get_addr_by_id(20);
delete_link(addr);
delete_memlink();
}
int main()
{
MemLink ml;
ml.link_test();
return 0;
}
審核編輯:劉清
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
printf函數
+關注
關注
0文章
31瀏覽量
5899
發布評論請先 登錄
相關推薦
探索字節隊列的魔法:多類型支持、函數重載與線程安全
探索字節隊列的魔法:多類型支持、函數重載與線程安全代碼難度指數:文章學習重點:參數宏的使用技巧一、引言在嵌入式系統和實時應用中,數據的傳輸和處理是至關重要的。字節
Freertos隊列項里的字節長度是否可以獲???
最近剛學Freertos, 看到可以獲取Freertos隊列長度,但是隊列項里的字節長度是否可以獲???
因為項目中隊列中會存放不定長字節,
發表于 04-29 07:17
【MiCOKit試用體驗】慶科MiCO系統篇(4)MiCO RTOS消息隊列
, uint32_tnumber_of_messages );該函數為初始化一個消息隊列,參數1為指向要初始化的消息隊列的句柄指針;參數2為消息隊列的名稱,由用戶定義;參數3為將要進入隊列
發表于 10-24 17:03
keystoneII arm示例程序網卡中斷,請問隊列收到包后,如果暫時不從隊列中pop包,是否可以在隊列這個級別清除中斷信號?
描述:目前開發板示例程序網卡驅動中,接收用了queue-658,這個隊列的中斷信號直接給了中斷控制器,請問,如果隊列收到包后,如果暫時不從隊列中pop包的話,是否可以在
發表于 08-03 07:43
STM32使用靜態隊列保存數據 精選資料分享
最近在調試CAN總線接口的BootLoader。由于應用程序的代碼比較大,升級過程比較慢。所以在不斷的優化BootLoader程序,讓升級時間盡可能縮短。其中最重要的就是使用了隊列,而且使用的是靜態
發表于 08-20 06:02
為什么要使用消息隊列?消息隊列的優缺點
優化:問題1:為什么要使用消息隊列?問題2:消息隊列的優缺點?問題3:如何增強消息隊列使用的穩定性?問題1:為什么會使用消息隊列?由于業務劃
發表于 12-22 06:28
循環隊列的實用代碼的應用方式
循環隊列的實用代碼概念就不過多說明,直接上干貨,不好的地方請多擔待指正。功能說明:用一個藍牙模塊,利用串口接收/發送中斷,接收數據,發送數據的例子(注:如果要直接套用代碼,那發送中斷的模式必須設置為發送完成后中斷。即發送一個
發表于 01-21 07:26
簡單羅列幾種隊列管理邏輯電路
方式,比如移位寄存器。使用SpinalHDL實現FIFO的代碼如下。輸入輸出的push/pop,使用了valid/ready握手的Stream接口;使用Mem定義環形buffer,pushPtr
發表于 08-29 14:23
POP3協議和Base 64編碼原理
POP3適用于C/S結構的脫機模型,是因特網電子郵件的第一個離線協議標準,Base 64是一種很常見的編碼規范,被設計用來將任意序列的8字節描述為一種不易被人直接識別的形式
發表于 01-12 19:08
?2176次閱讀
RTOS消息隊列的多種用途
消息隊列可以以多種不同的方式使用。事實上,您可以編寫可能只使用消息隊列的相當復雜的應用程序。僅使用消息隊列可以減少代碼的大?。凑加每臻g),因為可以模擬許多其他服務(信號量、時間延
MCU專屬隊列功能模塊之QueueForMcu應用
當需要從隊列頭部獲取多個數據,但又不希望數據從隊列中刪除時,可以使用 Queue_Peek_Array 函數來實現,該函數的參數與返回值與 Queue_Pop_Array 完全相同。
發表于 03-20 11:44
?524次閱讀
評論