comparing two structs .. revisited

M

ma740988

There's a need for me to move around at specified offsets within
memory. As as a result - long story short - unsigned char* is the type
of choice.

At issue: Consider the case ( test code ) where I'm comparing two
structs. The struct test1 has information with regards to data_size
and pointer
to address. The struct test2 has information with regards to data_size
and value. I will compare test1 and test2. For each matching data
size, I'll will look within address (ptr_addr) in test1 for the
appropriate value. In this case 0xA9000000. To simulate this, I've put
together test code below.

Trouble is Visual Studio. NET complains about the find operation in
the compare function claiming :

" binary '==' : no operator found which takes a left-hand operand of
type 'const std::allocator<_Ty>::value_type' (or there is no
acceptable conversion)"

That puzzles me, since I'm doing _pretty much the exact same thing on
another machine - not readily accessible.

So now:

# include <iostream>
# include <algorithm>
# include <vector>
# include <string>

using namespace std;

typedef unsigned int uint_type;
typedef unsigned char* ADDR_TYPE;

struct test1
{
unsigned int data_size;
ADDR_TYPE ptr_addr;
test1(
uint_type data_size,
ADDR_TYPE ptr_addr
)
: data_size(data_size)
, ptr_addr(ptr_addr)
{}
};


struct test2
{
unsigned int data_size;
unsigned int value;
test2(
uint_type data_size,
uint_type value
)
: data_size(data_size)
, value(value)
{}
};

bool operator==( const test2& lhs, const test1& rhs ) {
ADDR_TYPE rhs_end = rhs.ptr_addr + rhs.data_size;
return
( lhs.data_size == rhs.data_size &&
find( rhs.ptr_addr, rhs_end, lhs.value )
!= rhs_end );
}


#if 0
bool operator==( const test2& lhs, const test1& rhs ) {
return rhs == lhs;
}


#endif
void compare( const vector<test1>& vec, const test2& s)
{
vector<test1>::const_iterator it = find( vec.begin(), vec.end(), s );
if ( it != vec.end() ) {
// found a test2 object that matches 's'
cout << " FOUND " << endl;
}
else {
// none there
}

}


int main()
{
ADDR_TYPE ptr_addr = new unsigned char [ 0x200000 ];
std::fill ( ptr_addr, ptr_addr + 0x200000, 0xA9000000);

typedef std::vector<test1> TEST1_VEC;
TEST1_VEC t1_vec;
test1 t1a(0x200000, ptr_addr );
test1 t1b(0x200000, ptr_addr );
t1_vec.push_back(t1a);
t1_vec.push_back(t1b);
test2 t2(0x200000, 0xA9000000 );


compare ( t1_vec, t2 );
}


In addition, within the code on the machine - that's not readily
accessible - I had to cast to unsigned int pointer before the compare
function returned true. i.e. I had to do:

find( (unsigned int*) rhs.ptr_addr, (unsigned int*)rhs_end, lhs.value )

!= (unsigned int*)rhs_end );

but it worked.
From the looks of things I might be better off using std::find_if()
wiith a function pointer or function object.
If that's the case could I get a source snippet on this?

I get the feeling the std::find() function is only guaranteed to
compile if a T is being searched within a container of T.
I'm still not sure why this would work on antother machine though (
though I might need to check again - to ensure there's no noticable
difference )

Not sure what I'm missing here.
Thanks in advance
 
D

Daniel T.

"ma740988 said:
There's a need for me to move around at specified offsets within
memory. As as a result - long story short - unsigned char* is the type
of choice.

At issue: Consider the case ( test code ) where I'm comparing two
structs. The struct test1 has information with regards to data_size
and pointer
to address. The struct test2 has information with regards to data_size
and value. I will compare test1 and test2. For each matching data
size, I'll will look within address (ptr_addr) in test1 for the
appropriate value. In this case 0xA9000000. To simulate this, I've put
together test code below.

Trouble is Visual Studio. NET complains about the find operation in
the compare function claiming :

" binary '==' : no operator found which takes a left-hand operand of
type 'const std::allocator<_Ty>::value_type' (or there is no
acceptable conversion)"

You need to fix the part inside the "#if 0" block so that test1 objects
can be compared to test2 objects.

But that's the least of your problems.
That puzzles me, since I'm doing _pretty much the exact same thing on
another machine - not readily accessible.

So now:

# include <iostream>
# include <algorithm>
# include <vector>
# include <string>

using namespace std;

typedef unsigned int uint_type;
typedef unsigned char* ADDR_TYPE;

struct test1
{
unsigned int data_size;
ADDR_TYPE ptr_addr;
test1(
uint_type data_size,
ADDR_TYPE ptr_addr
)
: data_size(data_size)
, ptr_addr(ptr_addr)
{}
};


struct test2
{
unsigned int data_size;
unsigned int value;
test2(
uint_type data_size,
uint_type value
)
: data_size(data_size)
, value(value)
{}
};

bool operator==( const test2& lhs, const test1& rhs ) {
ADDR_TYPE rhs_end = rhs.ptr_addr + rhs.data_size;
return
( lhs.data_size == rhs.data_size &&
find( rhs.ptr_addr, rhs_end, lhs.value )
!= rhs_end );

The problem with this find is basically like the 'fill' problem below.
As written, it checks if any 'unsigned char' in the ptr_addr equals the
value contained in an 'unsigned int' (in this case 0xa9000000, and there
is no way an unsigned char is going to contain 0xa9000000.)
Fix the below and remove the preprocessor

bool operator==( const test1& lhs, const test2& rhs ) {
bool operator==( const test2& lhs, const test1& rhs ) {
return rhs == lhs;
}


#endif
void compare( const vector<test1>& vec, const test2& s)
{

Nothing is wrong with this function, as long as the op==s are defined
properly.
vector<test1>::const_iterator it = find( vec.begin(), vec.end(), s );
if ( it != vec.end() ) {
// found a test2 object that matches 's'
cout << " FOUND " << endl;
}
else {
// none there
}

}


int main()
{
ADDR_TYPE ptr_addr = new unsigned char [ 0x200000 ];
std::fill ( ptr_addr, ptr_addr + 0x200000, 0xA9000000);

The code above creates a "fill<unsigned char*, unsigned int>" function,
and the problems begin... A char cannot hold the value 0xA9000000 so
what it ends up with is either 0xA900 or 0x0000 depending on the
endianness of the computer (I think, on my system each char ended up
with 0x0000.)
typedef std::vector<test1> TEST1_VEC;
TEST1_VEC t1_vec;
test1 t1a(0x200000, ptr_addr );
test1 t1b(0x200000, ptr_addr );
t1_vec.push_back(t1a);
t1_vec.push_back(t1b);
test2 t2(0x200000, 0xA9000000 );


compare ( t1_vec, t2 );
}


In addition, within the code on the machine - that's not readily
accessible - I had to cast to unsigned int pointer before the compare
function returned true. i.e. I had to do:

find( (unsigned int*) rhs.ptr_addr, (unsigned int*)rhs_end, lhs.value )

!= (unsigned int*)rhs_end );

but it worked.

It worked because then you were comparing apples to apples.
I get the feeling the std::find() function is only guaranteed to
compile if a T is being searched within a container of T.

Not at all. The problem is when the value can hold things that the items
in the container can't possible hold.
I'm still not sure why this would work on antother machine though (
though I might need to check again - to ensure there's no noticable
difference )

Not sure what I'm missing here.

You have a huge problem with comparing different types, but the problems
are hidden because the compiler is trying to be nice and automatically
typecast them for you rather than throwing up a diagnostic.

Simply fixing your op== as mentioned above, changing ADDR_TYPE to an
unsigned int*, and making a new unsigned int array (rather than an
unsigned char array) in main fixes the code.
 
M

ma740988

Nothing is wrong with this function, as long as the op==s are defined
properly.
A question for you. Indeed a lot of this amounts to a tendency for me
to mix to mix apples with oranges. The trouble with find is that
find stops after finding first match in the vector. I'd like to revise
that such that.

I'll search the entire vector for all matching such that:
I'll look at the address for the vector element. run from begin to end
on the address while comparing it with the desired value. The key
here is dont want to stop after the first match. While doing this I'll
keep track via a counter of the number of elements found.
So if vec<test1> was four. Count will be four. I'm experimenting with
an approahc here (utlizing count_if )but I suspect I could use your
expertise.
 
D

Daniel T.

Nothing is wrong with this function, as long as the op==s are defined
properly.
A question for you. Indeed a lot of this amounts to a tendency for me
to mix to mix apples with oranges. The trouble with find is that
find stops after finding first match in the vector. I'd like to revise
that such that.

I'll search the entire vector for all matching such that:
I'll look at the address for the vector element. run from begin to end
on the address while comparing it with the desired value. The key
here is dont want to stop after the first match. While doing this I'll
keep track via a counter of the number of elements found.
So if vec<test1> was four. Count will be four. I'm experimenting with
an approahc here (utlizing count_if )but I suspect I could use your
expertise.[/QUOTE]

There is an standard algorithm called "count" and another called
"count_if". Check them out.

<http://www.sgi.com/tech/stl/stl_index.html>
 
M

ma740988

There is an standard algorithm called "count" and another called
"count_if". Check them out.

<http://www.sgi.com/tech/stl/stl_index.html>

Actually I found just the right algorithm for what I need to do.

int main()
{
uint_type* ptr_addr = new uint_type [ 0x200000 ];
std::fill ( ptr_addr, ptr_addr + 0x200000, 0xA9000000);

uint_type *ptr_end = ptr_addr + 0x200000;
if ( std::search_n( ptr_addr, ptr_end, 0x200000, 0xA9000000 ) !=
ptr_end )
cout << " YES " << endl;
}

I'm all hooked on the C++ algorithms and containers now :). Real soon
I'll be able to put together the type of example you gave me two/three
weeks ago. Well I wish.

Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,262
Messages
2,571,048
Members
48,769
Latest member
Clifft

Latest Threads

Top