指针强制转换数据损坏 [英] data corruption on pointer cast
问题描述
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是一个实现
元素的类来获取哈希和==。哈希用于创建表
和==应该用于确保重复不存在
,但显然它不能正常工作。谢谢。
7月15日晚上10点56分,gara.m ... @ gmail.com写道:
Heyllo,
名称无光泽,
我实现了一个集合类如下:
模板< class T>
class元素
{
public:
virtual int operator ==(T)= 0;
virtual int hash()= 0;
};
/ **
*队列集的高效哈希实现,不允许添加重复项。
@author matt gara< gara.m ... @ gmail.com>
* /
模板< class T,int M = p>
class QueueSet
{
public:
...
int存在(元素< 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 /调试/./ SRC / sudokusolver [0x804a da1]
/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]
我已经完成了一些调试,看起来这个异常发生在
存在成员。我很确定异常是由
以下行引起的:
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;
}
....
};
它一直有效。它真的很奇怪,任何想法为什么之前的
都不起作用?
7月15日晚上11:09 ,gara.m ... @ gmail.com写道:
7月15日晚上10点56分,gara.m ... @ gmail.com写道:
Heyllo,
名称无光泽,
< blockquote class =post_quotes>
我实现了一个set类,如下所示:
template< class T>
class Element
{
public:
virtual int operator ==(T)= 0;
virtual int hash()= 0;
};
/ **
*队列集的高效哈希实现,不允许
添加重复项。
@author matt gara< gara.m ... @ 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]))
返回1;
返回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))
返回0; //未能添加
set [h] [size_t [h]] = elem;
size_t [h] + = 1;
size ++;
返回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/./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]
我已经做了一些调试,看起来好像发生在
存在的成员中。我非常肯定这个例外是由
以下行引起的:
if(*((T * )elem)== *((T *)set [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-> 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;
}
....
};
它一直有效。它真的很奇怪,任何想法为什么之前的
都不起作用?
2007-07-16 07: 56, ga*******@gmail.com 写道:
Heyllo,
名称无光泽,
我实现了如下集合类:
模板< class T>
class元素
{
public:
virtual int operator ==(T)= 0;
虚拟bool运算符==(const T&)= 0;
virtual int hash() = 0;
};
/ **
*队列集的高效哈希实现,不允许
添加重复项。
@author matt gara< ga ******* @ gmail.com>
* /
模板< class T,int M = p>
class QueueSet
{
public:
...
int存在(元素< 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] =(元素< T **)realloc(set [h],sizeof(Element< T >
*)*(max [h] + P));
不幸的是,我认为除了POD类型之外,还有任何保证realloc将
工作在C ++中使用
是非常危险的。
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];
size_t是标准
库中广泛使用的类型的名称,使用它作为标识符可能不是一个好主意。
int max [M];
...
};
抱歉,无法帮助解决您的问题,我只能在您的代码中指出其他一些
的东西。我注意到的一件事是你使用了很多指针,尝试使用引用。另外你可能想要将
元素作为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 allow
addition 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 add
set[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 an
exception:
*** 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 in
the exists member. I''m pretty certain the exception is caused by the
following line:
if ( *((T*)elem) == *((T*)set[h][i]))
which is weird because it works for the first 51st elements and then
throws this nutty error.
If the code doesn''t speak for itself, T is a class that implements
Element to get the hash and ==. The hash is used in creating the table
and the == is supposed to be used to make sure duplicated do not
exist, but clearly its not working properly. Thanks.
On Jul 15, 10:56 pm, gara.m...@gmail.com wrote: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 allow
addition of duplicates.
@author matt gara <gara.m...@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 add
set[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 an
exception:
*** 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 in
the exists member. I''m pretty certain the exception is caused by the
following line:
if ( *((T*)elem) == *((T*)set[h][i]))
which is weird because it works for the first 51st elements and then
throws this nutty error.
If the code doesn''t speak for itself, T is a class that implements
Element to get the hash and ==. The hash is used in creating the table
and the == is supposed to be used to make sure duplicated do not
exist, 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 previous
didn''t work?
On Jul 15, 11:09 pm, gara.m...@gmail.com wrote:On Jul 15, 10:56 pm, gara.m...@gmail.com wrote:
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 allow
addition of duplicates.
@author matt gara <gara.m...@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 add
set[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 an
exception:
*** 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 in
the exists member. I''m pretty certain the exception is caused by the
following line:
if ( *((T*)elem) == *((T*)set[h][i]))
which is weird because it works for the first 51st elements and then
throws this nutty error.
If the code doesn''t speak for itself, T is a class that implements
Element to get the hash and ==. The hash is used in creating the table
and the == is supposed to be used to make sure duplicated do not
exist, 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 previous
didn''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 previous
didn''t work?
On 2007-07-16 07:56, ga*******@gmail.com wrote:Heyllo,
Names matt,
I implemented a set class as follows:
template<class T>
class Element
{
public:
virtual int operator == (T) = 0;virtual bool operator==(const T&) = 0;
virtual int hash() = 0;
};
/**
* A efficient hash implementation of a Queue-set that does not allow
addition 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));Unfortunately I don''t think that there''s any guarantee that realloc will
work on anything except POD types, which makes it very dangerous to use
in C++.
max[h] += P;
}
if (exists(elem))
return 0; //failed to add
set[h][size_t[h]] = elem;
size_t[h] += 1;
size++;
return 1;
}
...
Element<T** set[M];
int size;
private:
int size_t[M];size_t is the name of a type used extensively throughout the standard
library, using it as an identifier might not be a good idea.
int max[M];
...
};Sorry, can''t help you with your problem, I can only point out some other
things in your code. One thing I noticed was that you use an awful lot
of pointers, try using references instead. Also you might want to make
Element a private class to QueueSet and make it''s use transparent to the
user, require instead that the elements are comparable and let the user
supply 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
这篇关于指针强制转换数据损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!