![]() |
| | #1 |
| Registered User Join Date: Dec 2008
Posts: 183
| info on memset and recv Code: memset(buffer, 0, sizeof(buffer)); I had a problem before in a program but when i added memset to it it worked good i wanna why in most cases they do memset isnt buffer alrdy doesnt have anything inside it why would i memset it ? |
| lolguy is offline | |
| | #2 |
| and the hat of vanishing Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,214
| - Lazyness - Hide bugs - "voodoo" programming In short, it's a waste of time if your use of recv() is correct.
__________________ If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. Up to 8Mb PlusNet broadband from only £5.99 a month! |
| Salem is offline | |
| | #3 |
| CSharpener Join Date: Oct 2006
Posts: 5,242
| in other words - it is workaround to ensure the received buffer is nul-terminated string when the usage of recv() is incorrect. So instead of using this CPU consuming workaround - better way is to fix the usage of recv()
__________________ If I have eight hours for cutting wood, I spend six sharpening my axe. |
| vart is offline | |
| | #4 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| The reason for this is that recv DOES NOT ADD A NULL TERMINATOR. However, if there is a '\0' at the end of the string read by recieve -- which would be "proper" -- then it will be included, presuming the buffer is big enough. However, sometimes with networking you cannot be held responsible for the string you are receiving, so you may want to make sure it is null terminated if you need it to be. Also, you are not guaranteed to "recv" the entire string, which means if you "properly" presume it will be there, it may not. Usually the answer to this is to keep trying, but it is also a good idea to make sure in the end, by adding a null terminator to the end after the recv call. memset'ing the buffer first will accomplish the same thing, and although it would not be my choice of methods, I have to say that vart and Salem are both way, way, way off base when they claim the point is to cover a bug or because the use of recv is "incorrect". There is nothing "incorrect", "voodooish", or even "hackish" about the use of memset here and the OP is correct in observing that it is commonly done. It is NOT a sign of bad programming, it's a programming preference. My preference would be to add or at least check for the null terminator after the recv, which seems more optimal.
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
| | #5 |
| and the hat of vanishing Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,214
| > I have to say that vart and Salem are both way, way, way off base when they claim the point is to cover a bug or because the use of recv is "incorrect". Example Code: memset( buff, 0, sizeof buff ) recv( sock, buff, sizeof buff, 0 ); a) the memset was a complete and utter waste of time, b) the resulting buffer STILL DOES NOT have a \0, nor does it have room for one either. In other words, a total loss. Consider Code: // drop the -1 if you're not interested in making a string
n = recv( sock, buff, sizeof buff - 1, 0 );
if ( n > 0 ) {
buff[n] = '\0'; // if you really want a \0 string
// do stuff with 'n' bytes
}
In any event, the real size of the received data is available to make sure you can do the right thing. > My preference would be to add or at least check for the null terminator after the recv, which seems more optimal. Who said that you were going to get a \0 from recv() Who said that you were going to receive it in a timely manner, even if it was sent? It's quite simple. Use the return result of the function properly, and you're not going to go wrong.
__________________ If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. Up to 8Mb PlusNet broadband from only £5.99 a month! |
| Salem is offline | |
| | #6 | |||
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| Quote:
However, I still can't say that it's wrong to use memset there. You just made up a ridiculous example: Code: memset( buff, 0, sizeof buff ) recv( sock, buff, sizeof buff, 0 ); Then you reinterate two points that I made explicitly, as if I had not accounted for them, which I did -- explicitly: Quote:
Quote:
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS | |||
| MK27 is offline | |
| | #7 |
| and the hat of vanishing Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,214
| > The error here IS NOT MEMSET, it's that the recv parameter should be "sizeof buff" minus 1. Thanks for pointing out that memset() is useless in this context. As for "made up" examples, you've no idea how many times I've seen people forget the -1, then wonder WTF is going on.
__________________ If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. Up to 8Mb PlusNet broadband from only £5.99 a month! |
| Salem is offline | |
| | #8 | |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,258
| Quote:
Code: #define THISROCKS { \
size_t thisrocks = 1; \
while( thisrocks++ ); \
}
...
THISROCKS
// drop the -1 if you're not interested in making a string
n = recv( sock, buff, sizeof buff - 1, 0 );
THISROCKS
if ( n > 0 ) {
THISROCKS
buff[n] = '\0'; // if you really want a \0 string
// do stuff with 'n' bytes
}
Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? | |
| quzah is offline | |
| | #9 |
| Registered User Join Date: Dec 2008
Posts: 183
| also today i Noticed while coding that send doesnt send Null terminator with send itself you have to add strlen(buffer)+1 maybe thats the case with memset |
| lolguy is offline | |
| | #10 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,258
| Memset will set however many bytes you tell it to. It's not its fault you passed it the wrong number of bytes. The same thing goes for recv. Hell, all functions for that matter. It's not really their job to double check everything you pass it to make sure it is what you thought it was. It's nice to provide in-function error checking, but really, there's no way for you to know that the buffer you've been passed is supposed to be only 99 bytes instead of 100. To think it's the function's fault is just silly. Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #11 |
| Registered User Join Date: Dec 2008
Posts: 183
| well i m not saying its the function fault I was just curious why memset when i pass to buffer it fixes it now i now that i Should also add +1 for strlen to add the Null character to the string |
| lolguy is offline | |
| | #12 | |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,258
| Because... man strlen Quote:
Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? | |
| quzah is offline | |
| | #13 |
| and the hat of vanishing Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,214
| > now i now that i Should also add +1 for strlen to add the Null character to the string But you're still wrong. Just because you managed to send(*) 12 bytes of "hello world\0" doesn't mean that the recv call will get all 12 bytes in a single call. It's perfectly allowed to receive "hell" on the first call and then "o world\0" on the second call. Sadly for you, your mis-handling of the code drags it through the brier patch and it is now slowly bleeding to death. TCP is a stream protocol, which means the only guarantee you have is the order of bytes. The number of bytes sent in a single send() call has NOTHING to do with the number of bytes in some subsequent recv() call. So your thinking of "I've sent a \0, why isn't it working" is just another symptom of the problem. The Eight Fallacies of Distributed Computing No doubt your early "success" sending to yourself @127.0.0.1 might lead you to think otherwise, but you only figure out what latency means when you travel .uk to .nz memset() here, send a \0 there - you seem to be doing EVERYTHING to try and make sure there is a \0 there for you to use, yet all the while you continue to miss the target. USE the return result of recv() and stop messing about. It's the only thing which can and will work. All this voodoo will fail you at some point. (*) I might also add that send() doesn't guarantee to send the whole message in a single call either.
__________________ If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. Up to 8Mb PlusNet broadband from only £5.99 a month! |
| Salem is offline | |
| | #14 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 396
| I dont really understand why we should add +1 to send. If you send for example "hello" which is 5 bytes + 1 for the '\0'. It will send "hello" + 1 byte which will be a garbage char because send() doesnt put '\0' at the end either. Code: send(mySocket, "hello", 6, 0); So now if you do Code: buffer[i] = '\0'; So wouldnt it be better to send only strlen(buffer) without the +1 ?
__________________ Using Code::Blocks,MingW with Windows. Last edited by Ducky; 11-08-2009 at 07:17 AM. |
| Ducky is offline | |
| | #15 | |
| int x = *((int *) NULL); Join Date: Jul 2003 Location: Banks of the River Styx
Posts: 891
| Quote:
Code: {'h', 'e', 'l', 'l', 'o', '\0'}
Code: send(s, "hello", 5, 0); // or strlen("hello")
Code: send(s, "hello", 6, 0); // or strlen("hello") + 1
Now, you need some sort of serialization of data between the two. Unless you only plan on sending on string, you'll need something to break up the strings. A null terminator, or a length prefix. The recv()ing side will have to buffer the data appropriately. send() is a very simple function. It sends a buffer of so many bytes. Likewise, recv() receives a buffer of so many bytes. Neither function knows anything about strings - that's way out of their scope. It send()s/recv()s data - ie, arrays of bytes. Period. You have to implement the protocol from point A to point B.
__________________ long time; /* know C? */ Unprecedented performance: Nothing ever ran this slow before. Any sufficiently advanced bug is indistinguishable from a feature. Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31. The best way to accelerate an IBM is at 9.8 m/s/s. recursion (re - cur' - zhun) n. 1. (see recursion) | |
| Cactus_Hugger is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|