第一次调用后LinkedListNode变量变为null [英] LinkedListNode variable became to null after the first call
问题描述
我将LinkedListNode< float>设置为m_CurIter = null作为私有成员,并设置一个布尔变量m_bFirstCall = true,如果m_bFirstCall为true,则在调用Update(...)时将m_CurIter = m_TrendList.First(首次调用)将m_bFirstCall设置为false;
但是,在第一次之后调用Update(...)时,私有成员m_CurIter变为null!如何解决C ++运作良好的问题.
DeTrend.cs
I made LinkedListNode<float> m_CurIter = null as a private member, and set a boolean variable m_bFirstCall = true, when called Update(...) if the m_bFirstCall is true then m_CurIter = m_TrendList.First (be called at first time) the m_bFirstCall be set to false;
However when called Update(...) after the first time, the private member m_CurIter became to null! How to fix such issue that C++ worked well.
DeTrend.cs
public class DeTrend
{
public DeTrend(int nWindowSize, int nPointSize)
{
if (nPointSize < nWindowSize)
throw new Exception("nPointSize < nWindowSize");
m_nWindowSize = nWindowSize;
m_nPointSize = nPointSize;
m_TrendList = new LinkedList<float>();
}
public void Dispose()
{
if (null != m_TrendList) m_TrendList.Clear(); m_TrendList = null;
}
public void Update(float[] inY, float[] outY, int nPointSize)
{
int i;
m_nPointSize = nPointSize;
if (m_nPointSize < m_nWindowSize) throw new Exception("nPointSize < nWindowSize");
for (i = 0; i < m_nPointSize; i++)
{
m_TrendList.AddLast(inY[i]);
}
if (m_bFirstCall)
{
m_CurIter = m_TrendList.First;
}
for (i = 0; i < m_nPointSize; i++)
{
// FIXME: m_CurIter became null after the first call ?
outY[i] = m_CurIter.Value - m_PreNMeanVal();
m_CurIter = m_CurIter.Next;
}
i = m_nPointSize - m_nWindowSize;
while (0 != i)
{
m_TrendList.RemoveFirst();
i--;
}
m_bFirstCall = false;
}
#region Private Variable
private bool m_bFirstCall = true;
private int m_nWindowSize = 101;
private int m_nPointSize = 200;
private LinkedList<float> m_TrendList = null;
private LinkedListNode<float> m_CurIter = null;
#endregion
private float m_PreNMeanVal()
{
float nRet = 0.0f;
float nTotal = 0.0f;
int i, nCount = 0;
LinkedListNode<float> iter;
// XXX: From WindowSize to CurIter
for (iter = m_TrendList.First; m_CurIter != iter; ) iter = iter.Next;
for (i = 0; i < m_nWindowSize && iter != m_TrendList.First; i++)
{
nTotal += iter.Value;
nCount++;
iter = iter.Previous;
}
if (0 == nCount) return nRet;
nRet = nTotal / nCount;
return nRet;
}
}</float></float></float></float>
DeTrend.cpp运作良好,但C#的DllImport很奇怪
DeTrend.cpp worked well but DllImport by C# weired
///////////////////////////////////////////////////////////////////////////////
// DeTrend Class
namespace CCTEC
{
class DeTrend
{
// Construct / Destruct
public:
DeTrend(int nWindowSize, int nPointSize)
{
if (nPointSize < nWindowSize) throw "WindowSize < PointSize";
m_nWindowSize = nWindowSize;
m_nPointSize = nPointSize;
m_bFirstCall = true;
}
~DeTrend() { m_TrendList.clear(); }
// Operation
public:
void Update(float *inY, float *outY, int nPointSize)
{
m_nPointSize = nPointSize;
int i;
for (i = 0; i < m_nPointSize; i++)
{
m_TrendList.push_back(inY[i]);
}
if (m_bFirstCall)
{
m_CurIter = m_TrendList.begin();
}
for (i = 0; i < m_nPointSize; i++, m_CurIter++)
{
outY[i] = *m_CurIter - m_PreNMeanVal();
}
i = m_nPointSize - m_nWindowSize;
while (i)
{
m_TrendList.pop_front();
i--;
}
m_bFirstCall = false;
}
// Attribute
private:
int m_nWindowSize;
int m_nPointSize;
bool m_bFirstCall;
std::list<float> m_TrendList;
std::list<float>::iterator m_CurIter;
// Operation
private:
float m_PreNMeanVal()
{
float nRet = 0.0f;
float nTotal = 0.0f;
int i, nCount = 0;
std::list<float>::iterator iter;
// XXX: From WindowSize to CurIter
for (iter = m_TrendList.begin(); m_CurIter != iter;) iter++;
for (i = 0; i < m_nWindowSize && iter != m_TrendList.begin(); i++, iter--)
{
nTotal += *iter;
nCount++;
}
if (0 == nCount) return nRet;
nRet = nTotal / nCount;
return nRet;
}
};
};</float></float></float>
[edit]已添加代码块,忽略HTML ..."选项已禁用-OriginalGriff.[/edit]
[edit]Code blocks added, "Ignore HTML..." option disabled - OriginalGriff.[/edit]
推荐答案
DeTrend.cs库在C#
DeTrend.cs library in C#
<br />
<pre lang="cs"><br />
// TODO: DeTrend class acts like mathwords detrend(...)<br />
public class DeTrend<br />
{<br />
public DeTrend(int nWindowSize)<br />
{<br />
m_nWindowSize = nWindowSize;<br />
m_TrendList = new LinkedList<float>();<br />
}<br />
<br />
public void Dispose()<br />
{<br />
if (null != m_TrendList) m_TrendList.Clear(); m_TrendList = null;<br />
}<br />
<br />
public void Update(float[] inY, float[] outY, int nPointSize)<br />
{<br />
int i;<br />
m_nPointSize = nPointSize;<br />
if (m_nPointSize < m_nWindowSize) <br />
{<br />
throw new Exception("nPointSize < nWindowSize");<br />
}<br />
for (i = 0; i < m_nPointSize; i++)<br />
{<br />
m_TrendList.AddLast(inY[i]);<br />
}<br />
if (m_bFirstCall)<br />
{<br />
m_CurIter = m_TrendList.First;<br />
}<br />
for (i = 0; i < m_nPointSize; i++)<br />
{<br />
// FIXME: m_CurIter became to null after the first call<br />
outY[i] = m_CurIter.Value - m_PreNMeanVal();<br />
m_CurIter = m_CurIter.Next;<br />
}<br />
i = m_nPointSize - m_nWindowSize;<br />
while (0 != i)<br />
{<br />
m_TrendList.RemoveFirst();<br />
i--;<br />
}<br />
m_bFirstCall = false;<br />
}<br />
<br />
#region Private Variable<br />
private bool m_bFirstCall = true;<br />
private int m_nWindowSize = 101;<br />
private int m_nPointSize = 200;<br />
private LinkedList<float> m_TrendList = null;<br />
private LinkedListNode<float> m_CurIter = null;<br />
#endregion<br />
<br />
// XXX: What is the Preview N Mean Value?<br />
private float m_PreNMeanVal()<br />
{<br />
float nRet = 0.0f;<br />
float nTotal = 0.0f;<br />
int i, nCount = 0;<br />
LinkedListNode<float> iter;<br />
for (iter = m_TrendList.First; m_CurIter != iter; ) iter = iter.Next;<br />
for (i = 0; i < m_nWindowSize && iter != m_TrendList.First; i++)<br />
{<br />
nTotal += iter.Value;<br />
nCount++;<br />
iter = iter.Previous;<br />
}<br />
if (0 == nCount) return nRet;<br />
nRet = nTotal / nCount;<br />
return nRet;<br />
}<br />
}<br />
</pre><br />
LibDeTrend.cpp可以通过C#进行DllImport
LibDeTrend.cpp can be DllImport by C#
<br />
<pre lang="cpp"><br />
...<br />
#include <list><br />
<br />
///////////////////////////////////////////////////////////////////////////////<br />
// DeTrend Class<br />
namespace CCTEC <br />
{<br />
class DeTrend <br />
{<br />
// Construct / Destruct<br />
public:<br />
DeTrend(int nWindowSize) <br />
{<br />
m_nWindowSize = nWindowSize;<br />
m_bFirstCall = true; <br />
}<br />
~DeTrend() { m_TrendList.clear(); }<br />
<br />
// Operation<br />
public:<br />
void Update(float *inY, float *outY, int nPointSize) <br />
{<br />
int i;<br />
m_nPointSize = nPointSize;<br />
if (m_nPointSize < m_nWindowSize) throw "WindowSize > PointSize";<br />
for (i = 0; i < m_nPointSize; i++) <br />
{<br />
m_TrendList.push_back(inY[i]);<br />
}<br />
if (m_bFirstCall) <br />
{<br />
m_CurIter = m_TrendList.begin();<br />
}<br />
for (i = 0; i < m_nPointSize; i++, m_CurIter++) <br />
{<br />
outY[i] = *m_CurIter - m_PreNMeanVal();<br />
}<br />
i = m_nPointSize - m_nWindowSize;<br />
while (i) <br />
{<br />
m_TrendList.pop_front();<br />
i--;<br />
}<br />
m_bFirstCall = false;<br />
}<br />
<br />
// Attribute<br />
private:<br />
int m_nWindowSize;<br />
int m_nPointSize;<br />
bool m_bFirstCall;<br />
std::list<float> m_TrendList;<br />
std::list<float>::iterator m_CurIter;<br />
<br />
// Operation<br />
private:<br />
float m_PreNMeanVal() <br />
{<br />
float nRet = 0.0f;<br />
float nTotal = 0.0f;<br />
int i, nCount = 0;<br />
std::list<float>::iterator iter;<br />
for (iter = m_TrendList.begin(); m_CurIter != iter;) iter++;<br />
for (i = 0; i < m_nWindowSize && iter != m_TrendList.begin(); i++, iter--) <br />
{<br />
nTotal += *iter;<br />
nCount++; <br />
}<br />
if (0 == nCount) return nRet;<br />
nRet = nTotal / nCount;<br />
return nRet;<br />
}<br />
};<br />
};<br />
<br />
///////////////////////////////////////////////////////////////////////////////<br />
// Private Variable<br />
static CCTEC::DeTrend *m_DeTrend = NULL;<br />
<br />
///////////////////////////////////////////////////////////////////////////////<br />
// Public Operation<br />
DLLEXPORT void LibDeTrendInit(int nWindowSize) <br />
{<br />
m_DeTrend = new CCTEC::DeTrend(nWindowSize); <br />
}<br />
<br />
DLLEXPORT void LibDeTrendCleanup() <br />
{<br />
if (m_DeTrend) delete m_DeTrend; m_DeTrend = NULL; <br />
}<br />
<br />
DLLEXPORT void LibDeTrendUpdate(float *inY, float *outY, int nPointSize) <br />
{<br />
if (m_DeTrend) m_DeTrend->Update(inY, outY, nPointSize);<br />
}<br />
</pre><br />
C#测试用例,有2个DeTrend对象,Update(...)outYXXX输出很奇怪!
C# testcase, there are 2 DeTrend objects, the Update(...) outYXXX output weired!
<br />
<pre lang="cs"><br />
m_objDeTrend1 = new DeTrend(101, m_nPointSize);<br />
m_objDeTrend2 = new DeTrend(101, m_nPointSize);<br />
float[] outYInteg1 = new float[m_nPointSize];<br />
float[] outYDeTrend1 = new float[m_nPointSize];<br />
float[] outYInteg2 = new float[m_nPointSize];<br />
float[] outYDeTrend2 = new float[m_nPointSize];<br />
if (null != m_objDeTrend1) m_objDeTrend1.Update(outYInteg1, outYDeTrend1, m_nPointSize);<br />
if (null != m_objDeTrend1) m_objDeTrend1.Update(outYInteg2, outYDeTrend2, m_nPointSize);<br />
</pre><br />
更改您的Update()函数以引用out向量:
Change your Update() function to take a reference to the out vector:
public void Update(float[] inY, ref float[] outY, int nPointSize)
并称其为
and call it like
m_objDeTrend1.Update(outYInteg1, ref outYDeTrend1, m_nPointSize);
您的Update()函数也不正确,并且如果您再次输入它,它将中断.看来您应该完全跳过m_bFirstCall以避免出现悬空的指针m_CurIter.
Your Update() function is also incorrect, and will break if you enter it a second time. It looks like you should skip the m_bFirstCall altogether to avoid a dangling pointer, m_CurIter.
这篇关于第一次调用后LinkedListNode变量变为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!