I'm writing a Windows Service that allocates memory dynamically. I tried both c++'s new operator and C's malloc. They return (probably valid) pointer but when I try to dereference it the program crashes with Windows saying:
The instruction at "0x77c478ac"
referenced memory at "0x00cb9001". The
memory could not be "read".
BTW I guess the pointer is valid because the referenced memory is not NULL (0x00cb9001).
EDIT: Here is the code
/* This is a thread procedure that is
called when connection arrives
and its purpose is to serve as a
regular expression server.
*/
void threadProc(LPVOID *ptr){
SOCKET accSock = (SOCKET) *ptr;
void * foundPtr;
int recvdBytes;
char * literalPtr;
u_long iMode = 0;
literalPtr = new char [4096]; //this may cause the problem
//We allocate 4kb but in fact the first 2 kbs will be for
//for the literal string, the next 2 kb are for the result
//that must be returned
ioctlsocket(accSock, FIONBIO, &iMode); //the "parent" socket was nonblocking
if(literalPtr){
recvdBytes = recv(accSock, (literalPtr+1), 2048, 0); //BTW, recv returns -1
foundPtr = regexp_cmp(literalPtr, fBuffer, 0); //program crashes when calling this function
if(!foundPtr){
*(literalPtr+2048) = (int) 0;
send(accSock, (char *) (literalPtr+2048), 4, 0); //sending 4 NULLs
}
else {
send(accSock, (char *) (literalPtr+2048), 2048, 0);
}
shutdown (accSock, 0);
delete[] literalPtr;
return;
}
It's pretty funny, you have the answer commented in your code. recv returns -1, indicating that no bytes were read and there is an error, (why not check errno and see what the problem is?) and then you call regexp_cmp anyway on an uninitialized buffer. No wonder it crashes.
As a second point, your code it overly complex. For example, the buffer size is fixed. Why bother newing it? You can keep the buffer on the stack. Why share the same buffer for two different purposes? Just allocate 2 buffers; one for send and the other for recv. Then you don't need to deal with possibly problematic pointer math.
I'm assuming regexp_cmp(literalPt... treats lineralPt as a string: that string is not null terminated ( I can't see any code effort to terminate that string ) so the function simply overrun that buffer looking for the '\0' that never comes...
Related
bool sendMessageToGraphics(char* msg)
{
//char ea[] = "SSS";
char* chRequest = msg; // Client -> Server
DWORD cbBytesWritten, cbRequestBytes;
// Send one message to the pipe.
cbRequestBytes = sizeof(TCHAR) * (lstrlen(chRequest) + 1);
if (*msg - '8' == 0)
{
char new_msg[1024] = { 0 };
string answer = "0" + '\0';
copy(answer.begin(), answer.end(), new_msg);
char *request = new_msg;
WriteFile(hPipe, request, cbRequestBytes, &cbRequestBytes, NULL);
}
BOOL bResult = WriteFile( // Write to the pipe.
hPipe, // Handle of the pipe
chRequest, // Message to be written
cbRequestBytes, // Number of bytes to writ
&cbBytesWritten, // Number of bytes written
NULL); // Not overlapped
if (!bResult/*Failed*/ || cbRequestBytes != cbBytesWritten/*Failed*/)
{
_tprintf(_T("WriteFile failed w/err 0x%08lx\n"), GetLastError());
return false;
}
_tprintf(_T("Sends %ld bytes; Message: \"%s\"\n"),
cbBytesWritten, chRequest);
return true;
}
after the first writefile in running (In case of '8') the other writefile function doesn't work right, can someone understand why ?
the function sendMessageToGraphics need to send move to chess board
There are 2 problems in your code:
First of all, there's a (minor) problem where you initialize a string in your conditional statement. You initialize it as so:
string answer = "0" + '\0';
This does not do what you think it does. It will invoke the operator+ using const char* and char as its argument types. This will perform pointer addition, adding the value of '\0' to where your constant is stored. Since '\0' will be converted to the integer value of 0, it will not add anything to the constant. But your string ends up not having a '\0' terminator. You could solve this by changing the statement to:
string answer = std::string("0") + '\0';
But the real problem lies in the way you use your size variables. You first initialize the size variable to the string length of your input variable (including the terminating '\0' character). Then in your conditional statement you create a new string which you pass to WriteFile, yet you still use the original size. This may cause a buffer overrun, which is undefined behavior. You also set your size variable to however many bytes you wrote to the file. Then later on you use this same value again in the next call. You never actually check this value, so this could cause problems.
The easiest way to change this, is to make sure your sizes are set up correctly. For example, instead of the first call, you could do this:
WriteFile(hPipe, request, answer.size(), &cbBytesWritten, NULL);
Then check the return value WriteFile and the value of cbBytesWritten before you make the next call to WriteFile, that way you know your first call succeeded too.
Also, do not forget to remove your sizeof(TCHAR) part in your size calculation. You are never using TCHAR in your code. Your input is a regular char* and so is the string you use in your conditional. I would also advice replacing WriteFile by WriteFileA to show you are using such characters.
Last of all, make sure your server is actually reading bytes from the handle you write to. If your server does not read from the handle, the WriteFile function will freeze until it can write to the handle again.
I have a (one way) server- client communication by using "named pipe". It works so far fine, but if i close the client-programm (by pressing a specific button), i get the Error: "Run-Time Check Failure #2 - Stack around the variable 'buffer' was corrupted.
I know that the buffer-array from the named pipe allocates the memory, but after long searching on google i didn't find a way to solve this problem (to deallocate it).
I have to say that i am beginner on c++.
Code:
char buffer[1];
DWORD numBytesRead = 0;
BOOL result = ReadFile(
pipe,
buffer, // the data from the pipe will be put here
sizeof(buffer), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);
// object recognized, write data from inertaCube into file
if (buffer[0] != '0'){ // do something }
// close program by pressing left CTRL-button
if (GetAsyncKeyState(VK_LCONTROL)){
myMeasurement.close();
CloseHandle(pipe);
return 0;
}
The sizeof(buffer) will give you the size of char in your code, which is not // number of bytes allocated.
First question: I am confused between Buffers in TCP. I am trying to explain my proble, i read this documentation TCP Buffer, author said a lot about TCP Buffer, thats fine and a really good explanation for a beginner. What i need to know is this TCP Buffer is same buffer with the one we use in our basic client server program (Char *buffer[Some_Size]) or its some different buffer hold by TCP internally ?
My second question is that i am sending a string data with prefix length (This is data From me) from client over socket to server, when i print my data at console along with my string it prints some garbage value also like this "This is data From me zzzzzz 1/2 1/2....." ?. However i fixed it by right shifting char *recvbuf = new char[nlength>>3]; nlength to 3 bits but why i need to do it in this way ?
My third question is in relevance with first question if there is nothing like TCP Buffer and its only about the Char *buffer[some_size] then whats the difference my program will notice using such static memory allocation buffer and by using dynamic memory allocation buffer using char *recvbuf = new char[nlength];. In short which is best and why ?
Client Code
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[200] = "This is data From me";
int nBytes = 200, nLeft, idx;
nLeft = nBytes;
idx = 0;
uint32_t varSize = strlen (sendbuf);
bytesSent = send(ConnectSocket,(char*)&varSize, 4, 0);
assert (bytesSent == sizeof (uint32_t));
std::cout<<"length information is in:"<<bytesSent<<"bytes"<<std::endl;
// code to make sure all data has been sent
while (nLeft > 0)
{
bytesSent = send(ConnectSocket, &sendbuf[idx], nLeft, 0);
if (bytesSent == SOCKET_ERROR)
{
std::cerr<<"send() error: " << WSAGetLastError() <<std::endl;
break;
}
nLeft -= bytesSent;
idx += bytesSent;
}
std::cout<<"Client: Bytes sent:"<< bytesSent;
Server code:
int bytesSent;
char sendbuf[200] = "This string is a test data from server";
int bytesRecv;
int idx = 0;
uint32_t nlength;
int length_received = recv(m_socket,(char*)&nlength, 4, 0);//Data length info
char *recvbuf = new char[nlength];//dynamic memory allocation based on data length info
//code to make sure all data has been received
while (nlength > 0)
{
bytesRecv = recv(m_socket, &recvbuf[idx], nlength, 0);
if (bytesRecv == SOCKET_ERROR)
{
std::cerr<<"recv() error: " << WSAGetLastError() <<std::endl;
break;
}
idx += bytesRecv;
nlength -= bytesRecv;
}
cout<<"Server: Received complete data is:"<< recvbuf<<std::endl;
cout<<"Server: Received bytes are"<<bytesRecv<<std::endl;
WSACleanup();
system("pause");
delete[] recvbuf;
return 0;
}
You send 200 bytes from the client, unconditionally, but in the server you only receive the actual length of the string, and that length does not include the string terminator.
So first of all you don't receive all data that was sent (which means you will fill up the system buffers), and then you don't terminate the string properly (which leads to "garbage" output when trying to print the string).
To fix this, in the client only send the actual length of the string (the value of varSize), and in the receiving server allocate one more character for the terminator, which you of course needs to add.
First question: I am confused between Buffers in TCP. I am trying to
explain my proble, i read this documentation TCP Buffer, author said a
lot about TCP Buffer, thats fine and a really good explanation for a
beginner. What i need to know is this TCP Buffer is same buffer with
the one we use in our basic client server program (Char
*buffer[Some_Size]) or its some different buffer hold by TCP internally ?
When you call send(), the TCP stack will copy some of the bytes out of your char array into an in-kernel buffer, and send() will return the number of bytes that it copied. The TCP stack will then handle the transmission of those in-kernel bytes to its destination across the network as quickly as it can. It's important to note that send()'s return value is not guaranteed to be the same as the number of bytes you specified in the length argument you passed to it; it could be less. It's also important to note that sends()'s return value does not imply that that many bytes have arrived at the receiving program; rather it only indicates the number of bytes that the kernel has accepted from you and will try to deliver.
Likewise, recv() merely copies some bytes from an in-kernel buffer to the array you specify, and then drops them from the in-kernel buffer. Again, the number of bytes copied may be less than the number you asked for, and generally will be different from the number of bytes passed by the sender on any particular call of send(). (E.g if the sender called send() and his send() returned 1000, that might result in you calling recv() twice and having recv() return 500 each time, or recv() might return 250 four times, or (1, 990, 9), or any other combination you can think of that eventually adds up to 1000)
My second question is that i am sending a string data with prefix
length (This is data From me) from client over socket to server, when
i print my data at console along with my string it prints some garbage
value also like this "This is data From me zzzzzz 1/2 1/2....." ?.
However i fixed it by right shifting char *recvbuf = new
char[nlength>>3]; nlength to 3 bits but why i need to it in this way ?
Like Joachim said, this happens because C strings depend on the presence of a NUL-terminator byte (i.e. a zero byte) to indicate their end. You are receiving strlen(sendbuf) bytes, and the value returned by strlen() does not include the NUL byte. When the receiver's string-printing routine tries to print the string, it keeps printing until if finds a NUL byte (by chance) somewhere later on in memory; in the meantime, you get to see all the random bytes that are in memory before that point. To fix the problem, either increase your sent-bytes counter to (strlen(sendbuf)+1), so that the NUL terminator byte gets received as well, or alternatively have your receiver manually place the NUL byte at the end of the string after it has received all of the bytes of the string. Either way is acceptable (the latter way might be slightly preferable as that way the receiver isn't depending on the sender to do the right thing).
Note that if your sender is going to always send 200 bytes rather than just the number of bytes in the string, then your receiver will need to always receive 200 bytes if it wants to receive more than one block; otherwise when it tries to receive the next block it will first get all the extra bytes (after the string) before it gets the next block's send-length field.
My third question is in relevance with first question if there is
nothing like TCP Buffer and its only about the Char *buffer[some_size]
then whats the difference my program will notice using such static
memory allocation buffer and by using dynamic memory allocation buffer
using char *recvbuf = new char[nlength];. In short which is best and
why ?
In terms of performance, it makes no difference at all. send() and receive() don't care a bit whether the pointers you pass to them point at the heap or the stack.
In terms of design, there are some tradeoffs: if you use new, there is a chance that you can leak memory if you don't always call delete[] when you're done with the buffer. (This can particularly happen when exceptions are thrown, or when error paths are taken). Placing the buffer on the stack, on the other hand, is guaranteed not to leak memory, but the amount of space available on the stack is finite so a really huge array could cause your program to run out of stack space and crash. In this case, a single 200-byte array on the stack is no problem, so that's what I would use.
I'm having a problem with unix local sockets. While reading a message that's longer than my temp buffer size, the request takes too long (maybe indefinitely).
Added after some tests:
there is still problem with freeze at ::recv. when I send (1023*8) bytes or less to the UNIX socket - all ok, but when sended more than (1023*9) - i get freeze on recv command.
maybe its FreeBSD default UNIX socket limit or C++ default socket settings? Who know?
i made some additational tests and I am 100% sure that its "freeze" on the last 9th itteration when executing ::recv command, when trying to read message >= (1023*9) bytes long. (first 8th itterationg going well.)
What I'm doing:
The idea is to read in a do/while loop from a socket with
::recv (current_socket, buf, 1024, 0);
and check buf for a SPECIAL SYMBOL. If not found:
merge content of buffer to stringxxx += buf;
bzero temp buf
continue the ::recv loop
How do I fix the issue with the request taking too long in the while loop?
Is there a better way to clear the buffer? Currently, it's:
char buf [1025];
bzero(buf, 1025);
But I know bzero is deprecated in the new c++ standard.
EDIT:
*"Why need to clean the buffer*
I see questions at comments with this question. Without buffer cleanup on the next(last) itteration of reading to the buffer, it will contain the "tail" of first part of the message.
Example:
// message at the socket is "AAAAAACDE"
char buf [6];
::recv (current_socket, buf, 6, 0); // read 6 symbols, buf = "AAAAAA"
// no cleanup, read the last part of the message with recv
::recv (current_socket, buf, 6, 0);
// read 6 symbols, but buffer contain only 3 not readed before symbols, therefore
// buf now contain "CDEAAA" (not correct, we waiting for CDE only)
When your recv() enters an infinite loop, this probably means that it's not making any progress whatsoever on the iterations (i.e., you're always getting a short read of zero size immediately, so your loop never exits, because you're not getting any data). For stream sockets, a recv() of zero size means that the remote end has disconnected (it's something like read()ing from a file when the input is positioned at EOF also gets you zero bytes), or at least that it has shut down the sending channel (that's for TCP specifically).
Check whether your PHP script is actually sending the amount of data you claim it sends.
To add a small (non-sensical) example for properly using recv() in a loop:
char buf[1024];
std::string data;
while( data.size() < 10000 ) { // what you wish to receive
::ssize_t rcvd = ::recv(fd, buf, sizeof(buf), 0);
if( rcvd < 0 ) {
std::cout << "Failed to receive\n"; // Receive failed - something broke, see errno.
std::abort();
} else if( !rcvd ) {
break; // No data to receive, remote end closed connection, so quit.
} else {
data.append(buf, rcvd); // Received into buffer, attach to data buffer.
}
}
if( data.size() < 10000 ) {
std::cout << "Short receive, sender broken\n";
std::abort();
}
// Do something with the buffer data.
Instead of bzero, you can just use
memset(buf, 0, 1025);
These are 2 separate issues. The long time is probably some infinite loop due to a bug in your code and has nothing to do with the way you clear your buffer. As a matter of fact you shouldn't need to clear the buffer; receive returns the number of bytes read, so you can scan the buffer for your SPECIAL_SYMBOL up to that point.
If you paste the code maybe I can help. more.
Just to clarify: bzero is not deprecated in C++ 11. Rather, it's never been part of any C or C++ standard. C started out with memset 20+ years ago. For C++, you might consider using std::fill_n instead (or just using std::vector, which can zero-fill automatically). Then again, I'm not sure there's a good reason to zero-fill the buffer in this case at all.
I'm writing on c++ in VS2010 Windows 7. I try to read file of size 64 bytes. Here's the code:
BYTE* MyReadFile(FILE *f)
{
size_t result;
BYTE *buffer;
long lSize;
if (f == NULL)
{
fputs ("File error", stderr);
exit (1);
}
fseek (f, 0, SEEK_END);
lSize = ftell (f);
rewind (f);
//buffer = (BYTE*) malloc (sizeof(char)*lSize);
buffer = new BYTE[lSize];
if (buffer == NULL)
{
fputs ("Memory error", stderr);
exit (2);
}
result = fread (buffer, 1, lSize, f);
if (result != lSize)
{
fputs ("Reading error",stderr);
exit (3);
}
fclose (f);
return buffer;
}
When I get file size it is 64, but when I allocate memory for it with new BYTE[lSize] I get 80 bytes of space and thus strange sequence ээээ««««««««оюою is added to the end of buffer. Can you please tell me how to handle this?
There is an important difference between the number of bytes you have allocated, and the number of bytes that you see.
If lsize is 64, you have indeed allocated yourself 64 bytes. This does not mean that behind the screen the C++ run time will have asked exactly 64 bytes to Windows. In practice memory managers ask slightly more memory so they are able to do their own homework. Often these extra bytes are allocated BEFORE the pointer you get back from new/malloc so you will never see them.
However, that is not your problem. The problem is that you read 64 bytes from file using fread. There is no way that fread knows what kind of data you are reading. It could be a struct, a char buffer, a set of doubles, ... It just reads these bytes for you.
This means that if the file contains the characters "ABC" you will get exactly "ABC" back. BUT, in C, strings should be nul-terminated, so if you pass this buffer to printf, it will continue to scan memory until it finds a nul-character.
So, to solve your problem, allocate 1 byte more, and set the last byte to the nul character, like this:
buffer = new BYTE[lSize+1];
buffer[lSize] = '\0';
What is behind and above is called sentinel.It is used to check if your code does not exceed boundary of allocated memory.When your program overwrite this values, CRT library will report debug messages when you release your buffer.
Look here : http://msdn.microsoft.com/en-us/library/ms220938%28v=vs.80%29.aspx
Although this may look like a memory problem, its actually a printing problem (as #Mystical pointed out). You need to put a null termination if you are going to print out anything as a string, else memory will be wildy read till one is encountered (which is UB).
Try this instead:
buffer = new BYTE[lSize + 1];
if (buffer == NULL)
{
fputs ("Memory error", stderr);
exit (2);
}
result = fread (buffer, 1, lSize, f);
if (result != lSize)
{
fputs ("Reading error",stderr);
exit (3);
}
buffer[lSize] = '\0';
It'll ensure there is a null terminator at the end of the returned buffer.
When memory is allocated, it is not on a per byte basis. Instead it is allocated in aligned blocks of 8 or 16 bytes (possibly with a header at the start, before the pointer). This is usually not a problem unless you create lots (many millions) of little objects. This doesn't have to be a problem in C and isn't even a major problem in Java (which doesn't support array of objects or objects allocated on the stack).