Thread: invalid conversion from void* to int*

  1. #1
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55

    invalid conversion from void* to int*

    hi,

    This is part of an online tutorial I'm going through, which is written in C but I'm trying to learn C++. I've been able to deal with most C>C++ issues in the tutorial until now.

    From what I understand, (is?) this suppose to be typecasted ? I just don't know how to do that with pointers (yet) (still learning). Just looking for a (specific) solution to this particular problem, so I can move forward with learning the stuff I am doing.

    Any help (& other pointers) appreciated, thanks.

    I'm using Dev C++.


    Error message
    Code:
    \main.cpp invalid conversion from `void*' to `int*'
    Points to this line;
    Code:
       int *buf = GlobalAlloc(GPTR, sizeof(int) * count);
    Entire code;
    Code:
    #include <windows.h>
    
    #include "resource.h" 
    
    BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	switch(Message)
    	{
    		case WM_INITDIALOG:
    			// This is where we set up the dialog box, and initialise any default values
    
    			SetDlgItemText(hwnd, IDC_TEXT, "This is a string");
    			SetDlgItemInt(hwnd, IDC_NUMBER, 5, FALSE);
    		break;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case IDC_ADD:
    				{
    					// When somebody clicks the Add button, first we get the number of
    					// they entered
    
    					BOOL bSuccess;
    					int nTimes = GetDlgItemInt(hwnd, IDC_NUMBER, &bSuccess, FALSE);
    					if(bSuccess) 
    					{
    						// Then we get the string they entered
    						// First we need to find out how long it is so that we can
    						// allocate some memory
    
    						int len = GetWindowTextLength(GetDlgItem(hwnd, IDC_TEXT));
    						if(len > 0)
    						{
    							// Now we allocate, and get the string into our buffer
    
    							int i;
    							char* buf;
    
    							buf = (char*)GlobalAlloc(GPTR, len + 1);
    							GetDlgItemText(hwnd, IDC_TEXT, buf, len + 1);
    
    							// Now we add the string to the list box however many times
    							// the user asked us to.
    
    							for(i = 0;i < nTimes; i++)
    							{
    								int index = SendDlgItemMessage(hwnd, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)buf);
    
    								// Here we are associating the value nTimes with the item 
    								// just for the heck of it, we'll use it to display later.
    								// Normally you would put some more useful data here, such
    								// as a pointer.
    								SendDlgItemMessage(hwnd, IDC_LIST, LB_SETITEMDATA, (WPARAM)index, (LPARAM)nTimes);
    							}
    
    							// Dont' forget to free the memory!
    							GlobalFree((HANDLE)buf);
    						}
    						else 
    						{
    							MessageBox(hwnd, "You didn't enter anything!", "Warning", MB_OK);
    						}
    					}
    					else 
    					{
    						MessageBox(hwnd, "Couldn't translate that number :(", "Warning", MB_OK);
    					}
    
    				}
    				break;
    				case IDC_REMOVE:
    				{
    					// When the user clicks the Remove button, we first get the number
    					// of selected items
    
    					HWND hList = GetDlgItem(hwnd, IDC_LIST);
    					int count = SendMessage(hList, LB_GETSELCOUNT, 0, 0);
    					if(count != LB_ERR)
    					{
    						if(count != 0)
    						{
    							// And then allocate room to store the list of selected items.
    
    							int i;
    							int *buf = GlobalAlloc(GPTR, sizeof(int) * count);
    							SendMessage(hList, LB_GETSELITEMS, (WPARAM)count, (LPARAM)buf);
    							
    							// Now we loop through the list and remove each item that was
    							// selected.  
    
    							// WARNING!!!  
    							// We loop backwards, because if we removed items
    							// from top to bottom, it would change the indexes of the other
    							// items!!!
    
    							for(i = count - 1; i >= 0; i--)
    							{
    								SendMessage(hList, LB_DELETESTRING, (WPARAM)buf[i], 0);
    							}
    
    							GlobalFree(buf);
    						}
    						else 
    						{
    							MessageBox(hwnd, "No items selected.", "Warning", MB_OK);
    						}
    					}
    					else
    					{
    						MessageBox(hwnd, "Error counting items :(", "Warning", MB_OK);
    					}
    				}
    				break;
    				case IDC_CLEAR:
    					SendDlgItemMessage(hwnd, IDC_LIST, LB_RESETCONTENT, 0, 0);
    				break;
    				case IDC_LIST:
    					switch(HIWORD(wParam))
    					{
    						case LBN_SELCHANGE:
    						{
    							// Get the number of items selected.
    
    							HWND hList = GetDlgItem(hwnd, IDC_LIST);
    							int count = SendMessage(hList, LB_GETSELCOUNT, 0, 0);
    							if(count != LB_ERR)
    							{
    								// We only want to continue if one and only one item is
    								// selected.
    
    								if(count == 1)
    								{
    									// Since we know ahead of time we're only getting one
    									// index, there's no need to allocate an array.
    
    									int index;
    									int err = SendMessage(hList, LB_GETSELITEMS, (WPARAM)1, (LPARAM)&index);
    									if(err != LB_ERR)
    									{
    										// Get the data we associated with the item above
    										// (the number of times it was added)
    
    										int data = SendMessage(hList, LB_GETITEMDATA, (WPARAM)index, 0);
    
    										SetDlgItemInt(hwnd, IDC_SHOWCOUNT, data, FALSE);
    									}
    									else 
    									{
    										MessageBox(hwnd, "Error getting selected item :(", "Warning", MB_OK);
    									}
    								}
    								else 
    								{
    									// No items selected, or more than one
    									// Either way, we aren't going to process this.
    									SetDlgItemText(hwnd, IDC_SHOWCOUNT, "-");
    								}
    							}
    							else
    							{
    								MessageBox(hwnd, "Error counting items :(", "Warning", MB_OK);
    							}
    						}
    						break;
    					}
    				break;
    			}
    		break;
    		case WM_CLOSE:
    			EndDialog(hwnd, 0);
    		break;
    		default:
    			return FALSE;
    	}
    	return TRUE;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	LPSTR lpCmdLine, int nCmdShow)
    {
    	return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    In C++, unlike C, void* -> int* is not an automatic conversion, but must be explicitly requested (by you).

  3. #3
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55
    I'm aware of that, I just don't know how to do that with pointers at this stage (ie sytax), which is why I'm asking for help.
    Thanks
    Last edited by Tropod; 01-03-2009 at 06:57 PM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The fix on your offending line is;
    Code:
       int *buf = (int *)GlobalAlloc(GPTR, sizeof(int) * count);
    Quote Originally Posted by Tropod View Post
    I'm aware of that, I just don't know how to do that with pointers at this stage (ie sytax).
    Really? You understand that an implicit conversion is not allowed, but don't know how to do an explicit conversion? That's very unusual in my experience: it's more common for people to use explicit conversions of pointers too often, even when it's inadvisable, and have trouble accepting the concept of an implicit conversion.

    That's not a criticism of you, by the way. It's actually a criticism of how most people are taught (and how a lot of textbooks encourage bad practice). I'm enjoying the novelty that you've somehow managed to avoid that. It means there may be hope for future programmers to surpass bad teaching materials.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55
    Quote Originally Posted by grumpy View Post
    The fix on your offending line is;
    Code:
       int *buf = (int *)GlobalAlloc(GPTR, sizeof(int) * count);
    Got it working now
    Thank you so much!!!

    I had tried similar (albeit obviously non-working) variations to this, but to no avail; as I have touched on casting a little, just not like this. I didn't feel like spending the next 3-4 hours (yet again) trying to find a solution to such simple problem. And it does seem so simple now.

    Really? You understand that an implicit conversion is not allowed, but don't know how to do an explicit conversion? That's very unusual in my experience: it's more common for people to use explicit conversions of pointers too often, even when it's inadvisable, and have trouble accepting the concept of an implicit conversion.


    That's not a criticism of you, by the way. It's actually a criticism of how most people are taught (and how a lot of textbooks encourage bad practice). I'm enjoying the novelty that you've somehow managed to avoid that. It means there may be hope for future programmers to surpass bad teaching materials.


    Well I've jumped straight into trying to learn C++ (at my own pace), with no prior programming skills/knowledge at all. And so when I come across a problem like this, I usually have a tendency of trying to figure/learn it out myself, along with any/all readings I come across along the way (plus the tutorial dealt with this issue, just not specifically with this issue with pointers). And so guess I'm at the stage where I'm still trying to learn certain syntax's/formats.


    Once again, thanx!!!

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I have two advices for you.
    1) You are jumping too far ahead of you. Windows programming is by no means easy, and if you don't know typecasting, then obviously you do not know the basics.
    2) Don't use C tutorials as reference for C++. They poison your mind (the C++ part ). Use C++ tutorials instead. What works in C tutorials might not compile under C++ and is 99% of the time not the way to do it in C++.

    And since C++ is all about types, I want to reinforce this by linking you to do this: http://www.research.att.com/~bs/bs_faq2.html#whitespace
    The sample code uses both T* and T * for some weird reason.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User Drogin's Avatar
    Join Date
    Oct 2005
    Location
    Norway
    Posts
    105
    Since we're talking C++ facism...shouldnt this be the way?

    Code:
    int *buf = reinterpret_cast<int*>(GlobalAlloc(GPTR, sizeof(int) * count));

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    static_cast should probably be enough.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    Registered User Drogin's Avatar
    Join Date
    Oct 2005
    Location
    Norway
    Posts
    105
    static_cast should probably be enough.
    Maybe...
    If it works, it's because convertion from void* is allowed.

    But usualy when converting pointers, I've read that reinterpret_cast<> should be used.

  10. #10
    Registered User
    Join Date
    Jan 2008
    Posts
    70
    Using void pointers in C++ is inadvisable. I second Elysia's recommendations. You are only going to hurt you C++ code by using design strategies meant for C.

    edit: static_cast should be used for casting void* to typed pointers according to Effective C++.
    Last edited by Drac; 01-04-2009 at 03:20 PM.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Aside from all other discussion here, why does this code need to use GlobalAlloc, rather than either malloc (C-style) or new (C++ style)? Is it simply someones intention to show the code that doesn't use any C runtime library when there is a system call that does the same thing?

    [Actually, looking up GloablAlloc leads me to believe that GlobalAlloc is absolutely wrong here: http://msdn.microsoft.com/en-us/libr...96(VS.85).aspx - unless this code is intended to be used by Windows 3.1 or older].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how do you resolve this error?
    By -EquinoX- in forum C Programming
    Replies: 32
    Last Post: 11-05-2008, 04:35 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. invalid conversion from `char*' to `char'
    By Tommy7 in forum C++ Programming
    Replies: 3
    Last Post: 06-09-2005, 10:45 PM
  5. Invalid conversion from 'const void*' to 'void*' error
    By prawntoast in forum C Programming
    Replies: 3
    Last Post: 05-01-2005, 10:30 AM