我定义了一个结构ConstColor,里面保存了我常用的一些颜色值,都加了const参数的,在初始化表中初始化的。在开发中我在类中声明ConstColor结构的一个对象作为成员变量,可是在使用过程中,不知道什么时候发生的问题,竟然发现对象的一个成员变量的值发生了改变!!!我该如何找到是谁改变了我的const成员变量值的呢?

解决方案 »

  1.   

    应该是掉用了某个函数导致的溢出。
    可以用单步跟踪看是那一条语句导致的溢出。最有可能遇到问题的是调用windows的函数的方式不对,如有的函数要求你给一个int *len最为参数,这种情况下你必须调用两次这个函数,使用第一次函数返回的len申请空间再次调用此函数。
      

  2.   

    多半是buf的原因,检查一下内存泄漏
      

  3.   

    我看是你想错了或看错了,好像const与一般量变存的地方和方式不一样吧
      

  4.   

    const数据成员只在某个对象生存期内是常量,而对于整个类(或结构)而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。你要想建立在整个类中都恒定的常量,别指望const数据成员了,应该用类中的枚举常量或静态常量来实现。
    class A
    {
       enum{ red=0,blue=1,green=2};
       static const grey=128;
     ....
    }
      

  5.   

    在一个类里,使用const恢复它在C中的一部分意思,它在每个类对象里分配存储并代表一个值,这个值一旦被初始化以后就不能改变。在一个类里使用const的意思是“在这个对象寿命期内,这是一个常量”。然而,对这个常量来讲,每个不同的对象可以含一个不同的值。
      这样,在一个类里建立一个const时,不能给它初值,这个初始化工作必须发生在构造函数里,并且,在构造函数的某个特别地方。因为const必须在建立它的地方被初始化,所以在构造函数的主体里,const必须已初始化了,否则,就只有等等,直到在构造函数主体以后的某地方给初始化,这意味着过一会儿才给const初始化。当然,无法防止在构造函数主体的不同地方改变const值了。
      

  6.   

    经过一番调试,终于发现是使用_tcscpy拷贝两个字符串的时候导致了ConstColor成员的值突然改变。
    但是调用_tcscpy函数并不是对ConstColor成员做操作,他们根本是无关的呀。shootingstars(流星)说的是对的,肯定是出现了函数溢出,但是函数溢出是在什么情况下发生的呢?
      

  7.   

    另外:
    class A
    {
       enum{ red=0,blue=1,green=2};
       static const grey=128;
     ....
    }
    中的“static const grey=128;”对我来说很成问题,我在结构中这样声明变量:
    struct A
    {
        static COLORREF GrayColor = RGB(128, 128, 128);
    };是无法通过编译的。该怎么办呢?
      

  8.   

    _tcscpy函数的溢出还是问题的关键,这种溢出肯定会导致问题,这次只是刚巧导致了其他变量的改变,让我发现了,但是以后该如何避免这种溢出呢?
      

  9.   

    _tcscpy函数的溢出,ASSERT()一下,处理一下不就得了。
      

  10.   

    _tcscpy函数是微软提供的标准函数,我只能从为什么会导致_tcscpy函数溢出着手,而不能在_tcscpy函数函数里面下手。现在的关键就是这个为什么会溢出?
    两个字符串是相同大小的TCHAR数组。这该如何时候?
      

  11.   

    看我开始回答的贴子,如果没有错的话,应该是那个问题。
    这是我的血的教训得来的(花了将近一周时间才找到这个问题)。
    找找看有没有调用win api,参数是int *,lont *,PLONG之类的,好好看看调用方式。应该是两个变量使用了同一块内存(或者有交叉)。结果导致在给一个变量付值时也改动了另外一个。
      

  12.   

    shootingstars(流星):
    的确是你说的那个原因。非常感谢你的帮助,让我长了见识啊。
    不过,还没有找到导致这个问题的真正原因。
    我是在使用_tcscpy函数对两个字符串进行拷贝操作时导致了这个溢出问题。
    现在我用Memcpy代替了_tcscpy,感觉好像更加接近问题的本质了。
    因为在使用memcpy的时候,拷贝的内存大小是由我指定的,但是使用_tcscpy的时候复制的内容长短是两个字符串的大小——特别是由src字符串决定的,而我的src字符串有时是没有经过初始化的(别人传给我的值,我不能决定里面的内容,有人对方会给我一个没有经过初始化的字符串,我也没办法。为此我一直在寻求跳槽,想找一个明智一些的公司)。难道是我的那个成员变量在内存中刚好处在了一个不巧的位置 ,而_tcscpy函数把src字符串的内容加上一段本不属于src的内容一起向Dest字符串复制的时候刚好覆盖了我的const成员变量所在的内存空间?
      

  13.   

    可是我还是不敢确定,_tcscpy函数是微软提供的,怎么会存在这么大的bug呢?
      

  14.   

    哦,你还是没有完全明白我的意思。
    举个例子。

    void winapi(type,PLONG len);//这是某个windows api函数
    type a;//某种结构体
    int b;
    b=3;
    winapi(&a,sizeof(type));这时候b=?,是3吗?不一定,应为很多函数的结构体参数大小不是一定的,这种函数需要这样调用
    long len=0;
    type * a;
    winapi(a,len);
    a=(type*)malloc(len);
    winapi(a,len);
    这是因为结构体的大小可变,所以如果用前一种方式的话,很可能a的数据已经把b给冲掉了。这个不是_tcscpy的bug!仔细找找你的程序中有没有类似winapi的函数。
    当然也可能是其余的情况,也用可能导致两个变量地址的重合,但是绝对不是_tcscpy的问题。
      

  15.   

    shootingstars(流星):
    多谢你的提醒,万分感谢你的热心帮助。
    但是,这次真的是在调试的时候看到了我的const成员变量在执行和它无关的_tcscpy操作的时候突然发生改变,而且每次都是这样。
    你举的例子真的让我获益匪浅,多谢。^_^真高兴有你的帮助,谢谢。
      

  16.   

    关于_tcscpy,在ANSI下,它就是strcpy,在你不能保证源字符串的长度一定不大于你的目标字符串长度的情况下,你必须用strlen()来判断,否则肯定可能发生溢出。至于人家传给你一个没有初始化的字符串,呵呵,只好揍他一顿了。因为没初始化的字符串不一定为空。但我有点迷惑,问题真出在这里吗?