|
Ah, sry, I missed your point then.
I'm always a bit suspicious about forms of array initialization, so I automatically assumed that was what you're at.
Sure, the code is missing a const there, which makes me wonder if it has been compiled as C-code, rather than C++? But I wonder if it's even possible to compile the invocation of a socket object as C-code - I don't think it is...
|
|
|
|
|
It should still compile since the value of STRLEN is known at compile time.
|
|
|
|
|
Well, there's "should" and then there's the compiler itself.
int STRLEN = 512;
char recMessage[STRLEN] = "0";
1>c:\users\otoolec\documents\visual studio 2008\projects\test2\test2\test2.cpp(14) : error C2057: expected constant expression
1>c:\users\otoolec\documents\visual studio 2008\projects\test2\test2\test2.cpp(14) : error C2466: cannot allocate an array of constant size 0
Now add "const" and the following does compile:
const int STRLEN = 512;
char recMessage[STRLEN] = "0";
|
|
|
|
|
In fact it should not, as it would require the compiler to analyze the semantics of the code in order to make sure that the variable STRLEN is not being changed. Even though this could be done in an easy example like this, the syntax is just as wrong as a missed '; '. Have you ever seen a compiler insert a missing ';' for you, no matter how obvious the fix?
|
|
|
|
|
You're right. It would unnecessarily complicate things.
|
|
|
|
|
|
I'm not that familiar with the ClientSocket class but I have a few observations / questions.
1) Clearly you expect "recMessage" to be a null terminated string (you "cout" it)
2) Who puts the NULL character at the end of each message?
3) Your buffer is "STRLEN" characters long (assuming you fix the declaration), you tell RecvData to read "STRLEN" characters. Who accounts for the NULL? Either the buffer needs to be one character bigger or the RecvData should be for one character smaller.
4) there is nothing to indicate the length of the received message in that API so how do you know or verified that all messages are < 200 characters as you stated in another reply.
5) the memset at the end of the routine does nothing useful. While it looks OK, are you sure that statement is not causing the problem.
6) other folks have commented on the declaration "char recMessage[STRLEN]" where STRLEN is not a #define constant but a variable. I suspect this is not what is used in the actual compiled code.
|
|
|
|
|
|
Regarding 3) and the code you linked, you need to pass STRLEN-1 to the sub. RecvData takes a size (STRLEN in this case), passes it directly to recv() which returns in the variable i the amount of bytes read. Then buffer[i] is set to '\0'. Which means that in the second worst case you write size, so the 0-termination writes to index STRLEN, which means the buffer should be STRLEN+1 in size at least. In the worst case scenario, SOCKET_ERROR is returned from receive and you'll end up trying to write to buffer[-1] . So... please tell me that the code at the site is not what you are using... please.
|
|
|
|
|
Excellent point on the SOCKET_ERROR case and setting buffer[-1]. My 5
|
|
|
|
|
Good point, but you're addressing the wrong person. I was just assuming this is the implementation of Socket , but I haven't used Socket myself.
|
|
|
|
|
I am having a project which is for 32 bit platform.
I am adding 64 bit support also.
32 bit compilation is able to open & read registry while 64 bit compilation is not able to open registry.
I was opening HKEY_CLASSES_ROOT. I guess it might be related to permissions but I could not figure it out.
Even worse 64 bit compilation is not able to load swf while 32 compilation does it successfully.
Any guess why?
|
|
|
|
|
Is the program still running under 32 bits? It is possible then that the registry access worked, but was done on the HKEY_LOCAL_MACHINE\Software\WOW6432Node\Classes key (see MSDN[^].
For further information, check the return values from the registry function.
|
|
|
|
|
32 bit compilation works in both 32 bit & 64 bit. But I need a separate 64 bit edition so I am trying to do that. 64 bit runs but not able to open registry and swf. 64 bit compilation does not run on 32 bit
|
|
|
|
|
Could you debug through the 64 bit compilation and specifically post the return values from the registry functions, like RegCreateKeyEx (or RegOpenKeyEx) and also what the RegQueryValueEx function returns, and any other you are using in the particular piece of code that does not work.
It'd also help if you post your code. Without more information, we're flying blind here
|
|
|
|
|
Most likely the 32 bit EXE was given a local registry to play with, this is part of UAC legacy application handling.
The 64 bit EXE is not seen as a legacy application, and gets a proper slap on the fingers.
Usually it is during installation that one chooses what files should be opened with the application. Not something the application changes after installation.
|
|
|
|
|
I am confused with Imagelist_LoadBitmap. It certainly makes sense if we create an imagelist from ICON file(resource), because icon file can have multiple images.
But within Bitmap file, only one image can be contained. I wonder Imagelist_LoadBitmap always creates an imagelist initially with only one image contained?
|
|
|
|
|
When you create the image list, you specify the size of each image. LoadBitmap will divide the loaded image into appropriate sub-rectangles. The bitmap should contain properly sized images laid out horizontally.
|
|
|
|
|
How can I call 'ChangeString' from main and have the function change the passed char pointer to some other string value?
Thanks in advance.
#include <iostream>
using namespace std;
void ChangeChar(char* value)
{
*value = 'b';
}
void ChangeString(char* value[])
{
*value = "Changed!";
}
int main()
{
char c = 'a';
cout << c << endl;
ChangeChar(&c);
cout << c << endl;
char str[] = "Hello World";
cout << str << endl;
cout << str << endl;
system("pause");
return 0;
}
|
|
|
|
|
Technically you need a double pointer (a pointer to a pointer to char), you may use a reference:
void ChangeString(char* & value)
{
value = "Changed!";
}
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
In the following line str is an array, not a pointer so it cannot be changed by the ChangeString() function.
char str[] = "Hello World";
If you change it to
char* str = "Hello World";
then it should work.
The best things in life are not things.
|
|
|
|
|
Actually this is bad practice.
This code is good:
char str[] = "Hello World";
This code is bad:
char* str = "Hello World";
The difference? In the first example str is allocated on the stack and you have full read and write access to it.
On the second, str points to a memory location containing the string "Hello World", but this memory could be allocated in a static (read only) section. Or consider a piece of code where you have this string literal multiple times. A compiler might decide to store it once and make all references to the string point to the same location. Then when you change it in one location it changes in all, but that wasn't your intention!
Instead, you should consider using a const char*, or if you want to modify it use string functions.
const char* str = "Hello World";
char str[200] = "Hello World";
|
|
|
|
|
Without knowing the intention of the programmer, neither of your suggestions is 'good' or 'bad'. Either way, it has little to do with the OP's question.
The best things in life are not things.
|
|
|
|
|
Unfortunately, it has everything to do with your answer and code. Even though the OP is obviously new to C/C++, it doesn't hurt to learn good practices right from the start.
At any rate, it wasn't a suggestion: it's me saying that it is bad practice to use pointers and string literals in that way, for the reasons I explained. This is quite independent of the programmer's intentions.
So my point is: your solution was almost correct, except for that you should use 'const char*' everywhere to work with it like this. This could potentially save the OP lots of time trying to debug weird access violation errors later on, as the compiler will be able to inform you when you are doing something inappropriate that you are allowed to do when just defining it as 'char*'.
Now if you think I am entirely wrong and that it is in fact not poor practice, then I'd love to hear your arguments.
|
|
|
|
|
The other answers tell you how it can be done.
But there is a risk factor here, in that the size of the buffer is not known to the ChangeString function.
So it is always safe to pass in a second size parameter and only copy that many characters to the buffer inside the ChangeString function.
|
|
|
|