-5

I have next problem. I used int memcmp ( const void * ptr1, const void * ptr2, size_t num ); function to compare two void pointers which contain integers. This worked for me very well.

int firstValue = 5;
int secondValue = 3;
void* firstValueVoid;
void* secondValueVoid
firstValueVoid = new int(firstValue);
secondValueVoid = new int(secondValue);
int compare = memcmp(firstValueVoid, secondValueVoid, 4);
cout << compare << endl;

But, if I am trying to to the same for strings, it always shows that first value is less than second one.

string firstValue = "abc";
string secondValue = "a";
int testSize = firstValue.length();
void* firstValueVoid;
void* secondValueVoid
firstValueVoid = new string(firstValue);
secondValueVoid = new string(secondValue);
int compare = memcmp(firstValueVoid, secondValueVoid, testSize);
cout << compare << endl;

So compare value always becomes equal to -1. Even if I am making firstValue = "a"; secondValue = "a";. Please help someone. I already tried everything I had in my mind to fix this problem. Thank you in advance!

user2962977
  • 21
  • 2
  • 5
  • 3
    Why? Why `new`? Why `void*`? – David G Nov 08 '13 at 22:08
  • `firstValue.length();` with `int firstValue;`? What? – GManNickG Nov 08 '13 at 22:09
  • Because I have such an assignment in university. It is restricted to use templates. I must do binary tree by using void pointers, first for int, and then for string values. I have already done it for integers, now need for strings. – user2962977 Nov 08 '13 at 22:10
  • @GManNickG Sorry, I have edited. I just typed incorrectly. Anyway, the problem is not in this. – user2962977 Nov 08 '13 at 22:15
  • 1
    You need to read about what `type`s are, what pointers are, what classes are, what `new` is and where you need it and how you use it. You basically have to read a beginners guide. – Etherealone Nov 08 '13 at 22:17
  • 3
    Why are you using `memcmp()` to compare integers instead of comparing them directly? Why are you using `memcmp()` to compare strings instead of using the `strcmp()` family of functions, or the `std::string::compare()` method? `memcmp()` is for comparing **raw data** only. – Remy Lebeau Nov 08 '13 at 22:21
  • I have already told, because I am making Binary Tree for inserting integers/strings inside. Do not recommend me to make templates, or to use strcmp() to compare strings. I actually have to make it working by void pointers. – user2962977 Nov 08 '13 at 22:24
  • 3
    @user2962977 If you already know the answer, why are you asking? Let me tell you that you are not knowledgeable enough yet to be rejecting help. You do need help, and we can give you it. But only if you actually want it. You do need to know what is behind a `void*`. If you know what's there, cast it and do a proper comparison. If you don't know what's there, it's game over. Do not pass go. Do not collect £200. – David Heffernan Nov 08 '13 at 22:32
  • 4
    @user2962977 Lower your tone ... – πάντα ῥεῖ Nov 08 '13 at 22:59

2 Answers2

5

From cppreference:

int memcmp( const void* lhs, const void* rhs, std::size_t count );

Reinterprets the objects pointed to by lhs and rhs as arrays of unsigned char and compares the first count characters of these arrays. The comparison is done lexicographically.

In your case, you're comparing two std::string objects whose byte sequences differs from the buffer that holds the actual string. You're getting this error because these objects are not naked char arrays but rather actual classes.

Here is the note from the actual page (emphasis mine):

This function reads object representations, not the object values, and is typically meaningful for trivially-copyable objects only. For example, memcmp() between two objects of type std::string or std::vector will not compare their contents.

You should be using an array of char for this:

char abc[] = "abc";
char abd[] = "abd";

int bytes = std::min(sizeof abc, sizeof abd);

int c1 = memcmp(abc, abd, bytes);
int c2 = memcmp(abd, abc, bytes);

If you really need void*s:

void* a = abc;
void* b = abd;

int c1 = memcmp(reinterpret_cast<char*>(a),
                reinterpret_cast<char*>(b), bytes);

int c2 = memcmp(reinterpret_cast<char*>(b),
                reinterpret_cast<char*>(a), bytes);
Community
  • 1
  • 1
David G
  • 94,763
  • 41
  • 167
  • 253
  • Thank you for advice, but, actually, I already tried making the same by using the char array:( Can you please provide some example. Thank you! – user2962977 Nov 08 '13 at 22:17
  • @user2962977 Then just assign `void*`s to them (i.e `void* a = abc; void* b = abd;`) and `reinterpret_cast` them to `char*`. – David G Nov 08 '13 at 22:30
4

Just declare the pointers as char* or char[] (which essentially is the same in this case), and compare them like that. This works fine:

char firstValue[] = "abc";
char secondValue[] = "a";
int testSize = string(firstValue).size();

int compare = memcmp(firstValue, secondValue, testSize);

There's a working example at the C++ reference page too.

If you REALLY need the void pointers use them like this:

int someData1 = 35243242;
int someData2 = 34243251;

void *ptr1, *ptr2;

ptr1 = &someData1;
ptr2 = &someData2;

int testSize = sizeof(int);

int compare = memcmp((char*)ptr1, (char*)ptr2, testSize);
cout << compare << endl;

or with strings:

string someData1 = "sdadsasd";
string someData2 = "sdadsasd";

void *ptr1, *ptr2;
const char *c1, *c2;

c1 = someData1.c_str();
c2 = someData2.c_str();

ptr1 = (char*)c1;
ptr2 = (char*)c2;

int testSize = someData1.size();

int compare = memcmp(ptr1, ptr1, testSize);
Paweł Stawarz
  • 3,952
  • 2
  • 17
  • 26
  • 5
    @user2962977 yes, I've seen your first example. You alocate the memory with the new operator, making memory leeks and you're comparing strings, not char pointers. If you still can't figure it now - read the answer now. And me more polite to people trying to help you. – Paweł Stawarz Nov 08 '13 at 22:53
  • Actually, perfectly working only example with strings. Other have bugs. Thank you! – user2962977 Nov 09 '13 at 10:29