本文介绍了指针强制转换数据损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 Heyllo, 姓名无光泽, 我实现了以下集合课程: 模板< class T> class元素 { public: virtual int operator ==( T)= 0; virtual int hash()= 0; }; / ** *队列集的有效哈希实现,不允许添加重复项。 @author matt gara< ga ***** **@gmail.com> * / 模板< class T,int M = p> class QueueSet { public: ... int exists(Element< T * elem) { int h = elem-> hash()%M; for(int i = 0; i< size_t [ h]; i ++) if(*((T *)elem)== *((T *)set [h] [i])) 返回1 ; 返回0; } int add(元素< T * elem) { int h = elem-> hash()%M; if(size_t [h] == max [h]) { set [h] =(Element< T **)realloc(set [h],sizeof(Element< T> ) *)*(max [h] + P)); max [h] + = P; } if(exists( elem)) 返回0; //未能添加 set [h] [size_t [h]] = elem; size_t [h] + = 1; 尺寸++; 返回1; } ... 元素< T ** set [M]; int size; private: int size_t [M]; int max [M]; ... }; 它一直工作到我尝试添加第52个元素并抛出 异常: ***检测到glibc *** / home / matt / sudokusolver / debug /。 / src / sudokusolver:双免费或腐败(fasttop):0x0804d170 *** ======= Backtrace:======== = /lib/tls/i686/cmov/libc.so.6[0xb7dba7cd] /lib/tls/i686/cmov/libc.so.6(cfree + 0x90)[0xb7dbde30] /home/matt/sudokusolver/debug/./src/sudokusolver[0x8048d7c] /home/matt/sudokusolver/debug/./ src / sudokusolver [0x804ada1] /home/matt/sudokusolver/debug/./src/sudokusolver[0x804aeb6] /home/matt/sudokusolver/debug/./ SR c / sudokusolver [0x804a6f5] /home/matt/sudokusolver/debug/./src/sudokusolver[0x804a795] /home/matt/sudokusolver/debug/./ src / sudokusolver [0x804962d] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xdc)[0xb7d68ebc) / home / matt / sudokusolver /debug/./src/ sudokusolver(__ gxx_personality_v0 + 0x49)[0x8048911] 我已经完成了一些调试,看起来这个异常发生在 存在成员。我很确定异常是由 以下行引起的: if(*((T *)elem)== *(( T *)设置[h] [i])) 这很奇怪,因为它适用于前51个元素然后 抛出这个疯狂的错误。 如果代码不能说明问题,T是一个实现 元素的类来获取哈希和==。哈希用于创建表 和==应该用于确保重复不存在,但显然它不能正常工作。谢谢。 解决方案 请注意以下代码有效: 模板< class T> class Element { public: 虚拟布尔等于(T * elem)= 0; //虚拟int operator ==(T)= 0; virtual int hash()= 0; }; class QueueSet { .... int存在(元素< T * elem) { int h = elem-> hash()%M; for(int i = 0; i< size_t [h]; i ++) if(elem- >等于((T *)set [h] [i])) 返回1; 返回0; } .... }; 它一直有效。它真的很奇怪,任何想法为什么之前的 都不起作用? 我实现了一个set类,如下所示: 请注意以下代码有效: 模板< class T> class Element { public: 虚拟布尔等于(T * elem)= 0; //虚拟int operator ==(T)= 0; virtual int hash()= 0; }; class QueueSet { ... int存在(元素< T * elem) { int h = elem-> hash()%M; for(int i = 0; i< size_t [h]; i ++) if(elem-> equals((T *)set [h] [i])) 返回1; 返回0; } ... }; 它一直有效。它真的很奇怪,任何想法为什么之前的 都不起作用? 此外,此代码也有效: 模板< class T> class Element { public: //虚拟bool等于(T * elem)= 0; 虚拟int operator ==(T *)= 0; virtual int hash()= 0; }; class QueueSet { .... int exists(Element< T * elem) { int h = elem-> hash()%M; for(int i = 0; i< size_t [h]; i ++) if(* elem ==(T *)set [h] [i]) 返回1; 返回0; } .... }; 它一直有效。它真的很奇怪,任何想法为什么之前的 都不起作用? 虚拟bool运算符==(const T&)= 0; 不幸的是,我认为除了POD类型之外,还有任何保证realloc将 工作在C ++中使用 是非常危险的。 size_t是标准 库中广泛使用的类型的名称,使用它作为标识符可能不是一个好主意。 抱歉,无法帮助解决您的问题,我只能在您的代码中指出其他一些 的东西。我注意到的一件事是你使用了很多指针,尝试使用引用。另外你可能想要将元素作为QueueSet的一个私有类,并使它对 用户透明使用,而是要求元素具有可比性并允许用户 提供哈希函数作为模板参数: 模板<类T,类H,int M = p> class QueueSet {...}; 其中H是哈希函数。 - Erik Wikstr?m Heyllo, Names matt, I implemented a set class as follows: template<class T>class Element{public:virtual int operator == (T) = 0;virtual int hash() = 0;}; /*** A efficient hash implementation of a Queue-set that does not allowaddition of duplicates.@author matt gara <ga*******@gmail.com>*/template<class T, int M = p>class QueueSet{public: ... int exists(Element<T* elem){int h = elem->hash()%M;for (int i=0; i < size_t[h]; i++)if ( *((T*)elem) == *((T*)set[h][i]))return 1;return 0;}int add(Element<T* elem){int h = elem->hash()%M;if (size_t[h] == max[h]){set[h] = (Element<T**)realloc(set[h], sizeof(Element<T>*)*(max[h] + P));max[h] += P;}if (exists(elem))return 0; //failed to addset[h][size_t[h]] = elem;size_t[h] += 1;size++;return 1; } ... Element<T** set[M];int size;private:int size_t[M];int max[M];...}; And it works up until I try adding the 52nd element and it throws anexception: *** glibc detected *** /home/matt/sudokusolver/debug/./src/sudokusolver: double free or corruption (fasttop): 0x0804d170 ***======= Backtrace: =========/lib/tls/i686/cmov/libc.so.6[0xb7dba7cd]/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7dbde30]/home/matt/sudokusolver/debug/./src/sudokusolver[0x8048d7c]/home/matt/sudokusolver/debug/./src/sudokusolver[0x804ada1]/home/matt/sudokusolver/debug/./src/sudokusolver[0x804aeb6]/home/matt/sudokusolver/debug/./src/sudokusolver[0x804a6f5]/home/matt/sudokusolver/debug/./src/sudokusolver[0x804a795]/home/matt/sudokusolver/debug/./src/sudokusolver[0x804962d]/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xdc)[0xb7d68ebc]/home/matt/sudokusolver/debug/./src/sudokusolver(__gxx_personality_v0+0x49)[0x8048911]I''ve done some debugging and it looks like the exception happens inthe exists member. I''m pretty certain the exception is caused by thefollowing line: if ( *((T*)elem) == *((T*)set[h][i])) which is weird because it works for the first 51st elements and thenthrows this nutty error. If the code doesn''t speak for itself, T is a class that implementsElement to get the hash and ==. The hash is used in creating the tableand the == is supposed to be used to make sure duplicated do notexist, but clearly its not working properly. Thanks. 解决方案 Note that the following code works: template<class T>class Element{public:virtual bool equals(T * elem ) = 0;// virtual int operator == (T) = 0;virtual int hash() = 0;};class QueueSet{....int exists(Element<T* elem){int h = elem->hash()%M;for (int i=0; i < size_t[h]; i++)if (elem->equals((T*)set[h][i]))return 1;return 0;}....};It works all the time. Its really weird, any ideas why the previousdidn''t work? Note that the following code works:template<class T>class Element{public: virtual bool equals(T * elem ) = 0;// virtual int operator == (T) = 0; virtual int hash() = 0;};class QueueSet{... int exists(Element<T* elem) { int h = elem->hash()%M; for (int i=0; i < size_t[h]; i++) if (elem->equals((T*)set[h][i])) return 1; return 0; }...};It works all the time. Its really weird, any ideas why the previousdidn''t work?Also, this code also works: template<class T>class Element{public:// virtual bool equals(T * elem ) = 0;virtual int operator == (T*) = 0;virtual int hash() = 0; }; class QueueSet{....int exists(Element<T* elem){int h = elem->hash()%M;for (int i=0; i < size_t[h]; i++)if (*elem == (T*)set[h][i])return 1;return 0;}.... }; It works all the time. Its really weird, any ideas why the previousdidn''t work? virtual bool operator==(const T&) = 0; Unfortunately I don''t think that there''s any guarantee that realloc willwork on anything except POD types, which makes it very dangerous to usein C++. size_t is the name of a type used extensively throughout the standardlibrary, using it as an identifier might not be a good idea. Sorry, can''t help you with your problem, I can only point out some otherthings in your code. One thing I noticed was that you use an awful lotof pointers, try using references instead. Also you might want to makeElement a private class to QueueSet and make it''s use transparent to theuser, require instead that the elements are comparable and let the usersupply the hash-function as a template parameter: template<class T, class H, int M = p>class QueueSet { ... }; where H is the hash-function. --Erik Wikstr?m 这篇关于指针强制转换数据损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-18 23:58