第一次调用后LinkedListNode变量变为null [英] LinkedListNode variable became to null after the first call

查看:117
本文介绍了第一次调用后LinkedListNode变量变为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆