读书人

整两天了解决方法

发布时间: 2012-02-28 13:06:35 作者: rapoo

整两天了
在原系统上加模块
系统一加入模块,编译,链接都没有问题,运行就出现问题:Unhandled exception: Stack overflow
原先以为是我的函数调用部分数组越界了
但是后来F5调试后,显示的是原函数部分出问题。
后来干脆把数组设置较大,只打印较少的部分,依然是这个问题。
但是把我写的模块,哪怕是简单的的打印模块,注释掉后,系统就能运行。

应该就是调用如下这个函数出问题:
g_pTrigram-> GetNearProbAllLog(upNode-> GetUpTag(),upNode-> GetCurrentTag(),pdProb);
但是,没找到错误了,只是简单的调用啊,参数都是按照类型设置好的。

调用的相关函数以及自己写的测试main函数贴出来
望大侠指教,整两天了。~~~~~~~~~~~


/////////////////////////////////函数定义部分/////////////////////////
void CCorpStructInterpolate::GetNearProbAllLog(LONG lFirstTagNo, LONG lSecondTagNo, double

*pdProb)//通过传递两个LONG参数,获得pdProb数组
{
int iPos1;
int i, j;
double dTemp1;
float *pfTemp;
PLONG plTemp;

static int iLastPos = -1;
static LONG lLastSecondTag = -1;

if (lFirstTagNo> FUHAO) lFirstTagNo=1;
if (lSecondTagNo> FUHAO) lSecondTagNo=1;

iPos1 = FindPos(m_pStatData[lFirstTagNo].plFirstTagNo, m_pStatData

[lFirstTagNo].lNBinGrp, lSecondTagNo);

if ((iPos1 == iLastPos) && (lLastSecondTag == lSecondTagNo))
return;
iLastPos = iPos1;
lLastSecondTag = lSecondTagNo;

if ((lFirstTagNo == 0) && (lSecondTagNo == 0))
{

memcpy(pdProb, m_pProb0_1gram_exceptTag0, sizeof(double) * WORDSCOUNT);



if (iPos1 != -1) {
j = m_pStatData[lFirstTagNo].plNTriGrp[iPos1 + 1] - m_pStatData

[lFirstTagNo].plNTriGrp[iPos1];
plTemp = &m_pStatData[lFirstTagNo].plSecondTagNo[m_pStatData

[lFirstTagNo].plNTriGrp[iPos1]];
pfTemp = &m_pStatData[lFirstTagNo].pfTriProb[m_pStatData

[lFirstTagNo].plNTriGrp[iPos1]];
for (i = 1; i < j; i++)
pdProb[plTemp[i]] = LogAdd(pdProb[plTemp[i]], m_fCoffTrigram3

+ pfTemp[i]); //pdProb数组赋值,j=39936
}
j = m_pStatData[lSecondTagNo].lNBinGrp;
plTemp = m_pStatData[lSecondTagNo].plFirstTagNo;
pfTemp = m_pStatData[lSecondTagNo].pfBinProb;
dTemp1 = m_fCoffBigram3 - log(1 - exp(m_pStatData[0].pfBinProb[0]));
for (i = 1; i < j; i++)
pdProb[plTemp[i]] = LogAdd(pdProb[plTemp[i]], dTemp1 + pfTemp[i]);

//pdProb赋值,j=39936
return;
}

double fCoffUnigram, fCoffBigram, fCoffTrigram, fCoff0gram;
if (iPos1 != -1)
{
fCoffUnigram = m_fCoffUnigram3;
fCoffBigram = m_fCoffBigram3;
fCoffTrigram = m_fCoffTrigram3;
fCoff0gram = m_fCoff0gram3;
memcpy(pdProb, m_pProb0_1gram_3, sizeof(double) * WORDSCOUNT);
}
else
if (m_pStatData[lSecondTagNo].lNBinGrp > 0)
{
fCoffUnigram = m_fCoffUnigram2;
fCoffBigram = m_fCoffBigram2;
fCoff0gram = m_fCoff0gram2;
memcpy(pdProb, m_pProb0_1gram_2, sizeof(double) * WORDSCOUNT);//WORDSCOUNT=63996


}
else
{
fCoffUnigram = m_fCoffUnigram1;
fCoff0gram = m_fCoff0gram1;
memcpy(pdProb, m_pProb0_1gram_1, sizeof(double) * WORDSCOUNT);
}


//有bigram才可能有trigram
if (iPos1 != -1) {
j = m_pStatData[lFirstTagNo].plNTriGrp[iPos1 + 1] - m_pStatData

[lFirstTagNo].plNTriGrp[iPos1];
plTemp = &m_pStatData[lFirstTagNo].plSecondTagNo[m_pStatData

[lFirstTagNo].plNTriGrp[iPos1]];
pfTemp = &m_pStatData[lFirstTagNo].pfTriProb[m_pStatData

[lFirstTagNo].plNTriGrp[iPos1]];
for (i = 0; i < j; i++)
pdProb[plTemp[i]] = LogAdd(pdProb[plTemp[i]], fCoffTrigram + pfTemp

[i]);
}
j = m_pStatData[lSecondTagNo].lNBinGrp;
plTemp = m_pStatData[lSecondTagNo].plFirstTagNo;
pfTemp = m_pStatData[lSecondTagNo].pfBinProb;
for (i = 0; i < j; i++)
pdProb[plTemp[ i]] = LogAdd(pdProb[plTemp[i]], fCoffBigram + pfTemp[i]);

//pdProb赋值,j=39936
}

//////////////////////////////////函数调用部分/////////////////////////////

extern CCorpStructInterpolate *g_pTrigram;////////////外部声明,调用函数所必须的参数
extern ListNode* upNode=new ListNode; ////////外部声明,调用函数所必须的参数

void main()
{
double pdProb[100000];
g_pTrigram-> GetNearProbAllLog(upNode-> GetUpTag(),upNode-> GetCurrentTag(),pdProb);
ofstream out_prob( "out_prob.csv ",ios::out);
for(int i=0;i <3;i++)
out_prob < <pdProb[i] < < ', ' < <endl;
}

[解决办法]
提示不是很清楚嘛,栈溢出了。
你在栈里定义了太多东西。把一些太大的东西用new构建
[解决办法]
double pdProb[100000];
系统默认的栈只有1M大小,你看这都申请多大空间了?
大数组,都是用new 在堆上申请。
VC 可以在属性linker-> system下,修改栈大小,但是不推荐。
[解决办法]
1.可能是局部数组变量空间太大
办法有两个:
一是增大栈空间(后文中有详细描述)。
二是改用动态分配,使用堆(heap)而不是栈(stack)。
三将系统默认栈空间改一下:项目属性|配置属性|链接器|系统|堆栈保留大小

2.可能是memcpy出错
double pdProb[100000];//pdProb未初始化,理论上这里的指针是不该为NULL的,导致内存被改写
[解决办法]
不对. 我改主意了. 你还是先把两个全局对象的单间一下. 心安一点.

类似这样, 加两个函数:

Trigram & theTrigram() {
static Trigram t;
return t;
}
[解决办法]
哦, 指针, 那这样, 比如, 在CCorpStructInterpolate中, 加个static方法.大概如下:

class CCorpStructInterpolate {
public:
static CCorpStructInterpolate * instance() {
if(!instance) {
CCorpStructInterpolate::instance_ = new CCorpStructInterpolate;
}
return CCorpStructInterpolate::instance_;
}
private:
// 构造器放这里. 虽然是锦上添花.
static CCorpStructInterpolate * instance_;
};

另一个也是.

然后只通过CCorpStructInterpolate::instance()访问.

[解决办法]
改成static变量,不但可以解决栈溢出的问题,还可以大幅提高应用程序的性能,而且又不影响原有程序的结构和可读性

读书人网 >C++

热点推荐