如何用C++ stack容器来处理byte *

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用C++ stack容器来处理byte *相关的知识,希望对你有一定的参考价值。

问题是这样的:
Class T

public:
T(byte *pStreamA) : m_pStream(pStreamA)

~T();

void StreamProcess();

protected:
void GetWord(); // 从m_pStream流中读取一个单词,并放入m_Current[MAX]中

pirvate:
byte *m_pStream;

byte m_Current[MAX]; // 当前单词

stack<byte *> m_sStack;



void T::StreamProcess()

// 这里对m_pStream进行处理,如下:
while (...)


GetWord();
if (Compare(m_Current, tokenOne) // token指某些指定标记


Process(m_sStack.top()); // 遇到指定标记后进行处理,类似表达的处理,如

// 表达式 a * (b+c) ,略过前面,当遇到‘)’时,要进行

// 出栈入栈处理的问题,这里只是说明是类似的操作

m_sStack.pop();

continue;


if (Compare(m_Current, tokenTwo)



continue;


...

m_sStack.push(m_Current);



我的问题是:
次序 m_Current m_sStack 判断是否是指定标识 m_sStack
1 abc 入栈 否 abc
2 ced 入栈 否 ced

3 end 处理 是

这里做最简单处理:
cout << m_sStack; // 原意输出ced ,但是始终输出end
m_sStack.pop();

cout << m_sStack; // // 原意输出ced ,但是始终输出end
m_sStack.pop();
即m_sStack.pop始终指向m_Current中的内容,另外就是stack<byte *>是否需要析构?自己觉得问题就出在这里,m_Current值栈内存,并未分配内存,而是直接通过m_Current压入栈中,因此每当m_Current重新赋值时,stack.top()始终指向当前值,当时如果每次读一个单词就分配一块内存,并压入栈中的话,在进行处理的时候如果有有stack.pop();那在析构m_sStack时又该如何析构(被pop()出去的元素应该也有分配内存)。

我不是很看得懂你程序的语义,不知道stack到底是干什么的.
但是这句 m_sStack.push(m_Current)让人困惑.
假如当前
GetWord() ;
m_Current = "river"
stack.push( m_current ) ; // stack压入的是一个指针(m_current的地址),并不是整个字节值"river"
stack.top = "river" // 暂时等于"river"
然后你GetWord() to m_current = "riven"
你的stack.top 自动变成了 = "riven" // 这难道是设计刻意的安排吗?
// stack已经在无任何前兆的情况下,数据发生了改变
按照你上面的情况
阶段1: stack = abc
阶段2: stack = ced, ced
阶段3: stack = end, end, end

这种情况下,你要释放stack中的指针等于delete m_current.这肯定是错误的.

当然可能这也许是假象,我不是很懂你的程序的整体逻辑
作为路人甲发表点个人看法.追问

是的,你的解释我看懂了,是我的设计错了,我的原意就是要从给定的流中去读取数据进行操作,stack作为一个容器存放读出来的内容。大概是这样的想法:
1. stack = abc
2. stack = abc, ced
3. stack = abc, ced, end
4.如果该阶段遇到指定标识符进行出栈操作,pop出两个操作数之后 stack = abc
就是需要这样的功能,这样的话就需要为传入的每个元素分配内存,那这样的话最后如何对stack进行析构?

追答

最简单的方法就是
1. m_pStream改成流istream,ifstream对象
2. 把m_current类型改成string,读取流单词就编程了 istr >> m_current
3. stack改成stack,这样就没有释放内存的烦恼.

字节对象不一定就要叫做byte,C++标准库中字节缓冲区的类型为char*,比如cin.read( char* p, size_t n ) 用byte容易引起不兼容.,而char*是可以提升为string对象的
你既然使用了STL的stack,相信再使用string,istream等标准对象对你来说没什么限制.

追问

byte其实就是typedef unsigned char,主要是为了读入的时获取那些超过128的字符所以采用的byte,但是这样的话就没有直接从byte到string的提升了,要不然也不会这么麻烦了,如果我为stack中的每个元素都申请一段内存,到时应该如何析构?假设一共申请了10段内存,即stack中存放这10段内存的指针,最终在处理过程中全部pop掉,但是其指向内存还需要手动释放,那析构函数里面要如何进行处理?此时stack已空,那要如何释放内存?求解释

追答

inline void recycle( stack& s )

delete s.top() ;
stack.pop() ;

追问

这样的话就是在每次数据pop之前对其中元素先进行内存释放,然后pop掉,那析构函数里面似乎就不必在对stack进行操作了,是这样理解的的吗?我原来脑子没转过弯,一直认为在处理过程中只负责pop,然后内存释放由析构函数来负责,可是中间处理过程已经把stack中的元素全部pop完了,就糊涂了不知道该如何释放内存了,这样看来只要每次pop之前并释放其中指针元素指向的内存,就不必再在析构函数中对stack进行处理了,这样理解可否?

追答

是的,一旦你pop掉的话,你就没机会再释放内存了.
如果是动态数组,就用delete[] s.top() ;

参考技术A 你也没把指针操作相关的代码发上来,你说了一堆也没看明白。你的byte应该是typedef的char
m_pStream你是直接指向了构造的时候传进来的指针,这个指针指向的内存不应该由这个类负责;看样子你的stack里面存的是m_pStream里面的一部分,如果你不重新申请空间保存这些字符而是直接指向m_pStream指向的内存是不行的。如果你分配了空间,那么你pop的时候就要自己去释放空间,否则pop掉之后就没有指针指向这个空间就造成内存泄露了追问

byte是typedef unsigned char;
就是你说的这个意思,我的stack里面存的就是m_pStream的一部分,我是通过GetWord()去读取m_pStream中的内容,也就是穿进来指针指向的内容,然后放入m_Current数组;然后再把这个数组那去判断,当与指定的标识符相等时,进行处理,并没有重新分配内存,所以就照成内存泄露了,但是如果分配内存之后,在析构函数中该如何处理这个stack?怎么写这个析构函数

C++进阶-3-4stack容器queue容器

C++进阶-3-4stack容器、queue容器
C++进阶-3-4stack容器、queue容器

以上是关于如何用C++ stack容器来处理byte *的主要内容,如果未能解决你的问题,请参考以下文章

如何用C++调用halcon函数 (最好能详细点,谢谢)

UTF8原理是啥?如何用C编写UTF8的转换代码?

如何用Java实现条件编译

CADlisp编程:如何用lisp处理一个dwg图形中的多个多线段?

如何用c++将一个时间点转换成时间戳

请问如何用c++ 调用oracle存储过程?