指针强制转换数据损坏 [英] data corruption on pointer cast

查看:74
本文介绍了指针强制转换数据损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆