高分求教:关于CList,CString的奇怪问题

zte223456 2010-05-10 10:14:09
问题是这样的:
环境:windows Xp, vs2008,MFC, 多文档多视图
1)为了给各个文档都应用同一份初始数据,我在APP类里加了一个数据结构:
STATICDB m_stStaticDB; //静态信息库,用于模块创建的初始化模版
2)这个数据结构里面包含了一些CList, CString的成员,如下列出了一些成员(不全):
CString strCodeStart; //起始代码行字符串
char cCodeStartType; //用于固定代码行的代码模型选择,为0表示无效

CList<SCRIPTELEMENT,SCRIPTELEMENT&> listScriptElementList; //元素/分支列表
CString strCodeEnd; //结束代码行字符串
char cCodeEndType; //用于固定代码行的代码模型选择,为0表示无效
3)我在Mainframe的OnCreate函数中给这个结构中的变量赋初值:
m_stStaticDB.stInitData->stScript.cCodeEndType=1; //这个是给Char型成员赋值
m_stStaticDB.stInitData[0].stScript.strCodeStart="test"; //这个是给CString型成员赋值
4)编译通过
5)运行过程中报错,指针已经跑飞,我跟了一下,是在第二次进入一个函数后,返回的时候出的问题。
6)我把变量赋初值部分的给CString 和CList赋初值的代码注释起来,程序即可正常运行。
m_stStaticDB.stInitData[0].stScript.strCodeStart="test"; //即把这句注释起来
7)我自己考虑了一下,是不是这样的原因:
CString 和Clist 这样的类放在结构里面,在创建的时候会有问题?
具体是怎么样的,实在是想不通,还请高手指点!
8)还有就是请教如果这样的方式行不通,那么是不是必须用数组代替CString,而Clist也必须动态分配?有没有好一点的解决方案?谢谢!
...全文
318 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
bst2000 2012-05-07
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
结构体中 CList CString 成员放最后试试,可能是字节对齐的问题。
[/Quote]

我照着该过 运行通过了
zte223456 2010-05-11
  • 打赏
  • 举报
回复
非常感谢大家,我结贴了,感谢!
zte223456 2010-05-10
  • 打赏
  • 举报
回复
无解?
副组长 2010-05-10
  • 打赏
  • 举报
回复
想不周全就容易出问题,会引起程序不安全,所以我的经验是在结构里面尽量避免使用这些类。
结构是C特性,出现早,类是C++的,是后来的。早前下面的写法
STRUCT struct[10];
STRUCT struc1,struc2;
...
struc2 = struc1;
这些都是非常普通的用法,你放一些含有指向堆指针的类在里面,还是有楼上的例子,都非常容易出问题。
如果需要在成员里面有类类型,直接声明成类不就可以了?

非要在结构里面写类对象也不是不可以,但是把结构搞复杂了,这维护成本不是也增加了吗。
zte223456 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zhou1xp 的回复:]
把CString改为char *看看
[/Quote]

正解!!
但我当时用Cstring的想法是可以随意更改不同的字符串,因为初始的时候我不知道字符串会有多长,这样一来,如果初始化的长度不够的话,是不是还是会引起问题??
wangk 2010-05-10
  • 打赏
  • 举报
回复
CreateBlock这里return 出错,没有意外的话应该是堆栈溢出,Debug版本在函数退出的时候会检查堆栈。

那么应该是这个函数里面的代码问题了。

你可以在不同的行直接return,看看是哪一行导致的问题。
zhou1xp 2010-05-10
  • 打赏
  • 举报
回复
把CString改为char *看看
zte223456 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 tanwei1002 的回复:]
调试看看
你说的太抽象了,谁知道呀。。
[/Quote]

看看我的调试结果把,在12楼
zte223456 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wangk 的回复:]
在m_stStaticDB.stInitData[0].stScript.strCodeStart="test";这一行的时候
Watch一下相关的变量,如果没有问题的话,然后再用F11跟踪进去看看是什么问题。
[/Quote]

这句的赋值本身是没有问题的,我看过了,而且在我还用了他的初值都是没有问题的。但在在后面使用这些数据的函数出了问题
使用这个数据结构的函数如下
bool CSystem::CreateBlock(pPRECREATEINFO pinfo)
{
BLOCKELEMENTINFO defaultdata;
CBlockElement* pnewblock=NULL;
GetStaticDB(pinfo->iBlockTypeToCreat,defaultdata);
defaultdata.stRect.stLeftTop= pinfo->StartPt;
defaultdata.stRect.stRightBottom= pinfo->EndPt;
pnewblock=AppendBlock(&defaultdata);
if (NULL==pnewblock)
{
return false;
}
UpdateSystem(&defaultdata);
return true;

debug的结果在return true;这一行报错,中了断言,报错内容:


tanwei1002 2010-05-10
  • 打赏
  • 举报
回复
调试看看
你说的太抽象了,谁知道呀。。
wangk 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用楼主 zte223456 的回复:]
CString 和Clist 这样的类放在结构里面,在创建的时候会有问题?
[/Quote]

没有这回事,恐怕是你其他的地方的用法不对。

在m_stStaticDB.stInitData[0].stScript.strCodeStart="test";这一行的时候
Watch一下相关的变量,如果没有问题的话,然后再用F11跟踪进去看看是什么问题。
zte223456 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zhu6789888 的回复:]
结构体中 CList CString 成员放最后试试,可能是字节对齐的问题。
[/Quote]

开始我也怀疑过,已经试过了,不是这个问题。。。
finder_zhang 2010-05-10
  • 打赏
  • 举报
回复
为什么在结构体中不能使用CList?我想在结构体初期创建的时候应该自动的调clist的构造函数才对啊?

结构体可以用CList的,不会因为CList的增减而影响到其他的元素,MFC辛辛苦苦地搞个CList出来,不会连个类的成员变量也做不了的.
结构体与类是同样的工作原理,在创建时,的确会逐一调用所有成员的构造函数.

CList CString 这些,其实内部都是有指向堆中的指针.
如果你的结构里有 CList CString 的这些内容,这个结构体就不可以用memcpy来复制了.

struct MfcClsInc{
CList<int,int&> m_List;
CString m_str;
};

int main(int argc, char* argv[])
{
MfcClsInc mci1,mci2;
mci1.m_str = "abc";
memcpy(&mci2,&mci1,sizeof(MfcClsInc));
mci2.m_str = "a";//连同mci1一起改变,因为大家指向同一个地方
return 0;
}


这个代码在return时出错,原因是,CString这些,内部都是指向堆的指针,硬是COPY了之后,
2个结构指向同一个堆的指针,释构时,2次delete一个地方,就出错了.
zte223456 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wangk 的回复:]
m_stStaticDB.stInitData[0]???

只怕是这个时候stInitData还没有初始化,没有元素吧?
[/Quote]

#define BL_TYPE_COUNT 20

typedef struct tagStaticDB //静态模块初始信息
{
FILEVERSION stVersion; //版本信息
BLOCKELEMENTINFO stInitData[BL_TYPE_COUNT]; //存储顺序与enum BLOCK_TYPE相同

}STATICDB,*pSTATICDB;

这个是我没有说清楚,这是那个数据结构
在BLOCKELEMENTINFO 中有CList 和Cstring的成员
你说没有元素,能不能具体一点儿?
zhu6789888 2010-05-10
  • 打赏
  • 举报
回复
结构体中 CList CString 成员放最后试试,可能是字节对齐的问题。
Eleven 2010-05-10
  • 打赏
  • 举报
回复
不清楚你的代码中怎么写的,建议Debug调试跟踪一下
wangk 2010-05-10
  • 打赏
  • 举报
回复
m_stStaticDB.stInitData[0]???

只怕是这个时候stInitData还没有初始化,没有元素吧?
zte223456 2010-05-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zte223456 的回复:]
哪位高手能指教一下,非常着急,谢谢
[/Quote]

我这个程序是单线程
而且我在取消了对CString 的赋值以后就正常了,应该不是这个问题吧。。。
King030609 2010-05-10
  • 打赏
  • 举报
回复
顶下
jyh_baoding 2010-05-10
  • 打赏
  • 举报
回复
是不是其他的线程把地址改写了
加载更多回复(14)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧