View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
memset() using sizeof() vs length of buffer [CLOSED] |
Posted: Mon Dec 14, 2020 8:13 pm |
|
|
Good evening,
As an example to keep things simple, if I have this:
Code: |
unsigned char MyString[20]; |
If I want to clear it using memset, should I be doing this:
Code: | memset( MyString, NULL, sizeof( MyString )); |
or this:
Code: | memset( MyString, NULL, 20 ); |
Documentation states "Sets n number of bytes, starting at destination, to value. Be aware that array names are pointers where other variable names and structure names are not (and therefore need a & before them)" but their examples use sizeof()....
Thanks.
Ben
Last edited by benoitstjean on Thu Dec 17, 2020 3:55 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 14, 2020 8:57 pm |
|
|
sizeof( MyString ) is 20, so I'm not sure what your question is about. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Dec 14, 2020 9:11 pm |
|
|
I have many places where the code calls memset( String, NULL, sizeof( String )) but I figured maybe it would be a good idea instead to just pass whatever the size directly:
Let's say I have this:
Code: |
#define SIZE_OF_STRING 20
unsigned char MyString[SIZE_OF_STRING]; |
I was wondering if I should clear it like this:
Code: | memset( MyString, NULL, sizeof( MyString )); |
or like this:
Code: | memset( MyString, NULL, SIZE_OF_STRING ); |
I know it may sound trivial but earlier today I changed a bunch of memset to use the '#define' value in the memset rather than the sizeof() just to make it look cleaner and my code just went bonkers. It is quite possible that I screwed-up a few of them and used the wrong '#define' value in the memset therefore it is possible that when memset was called, it wrote further into memory than it should have had and corrupted the code which would explain the odd behaviour I am experiencing.
I'm going through my files with DiffMerge to compare known working files with the garbled files and reverting to the older memset which used sizeof....
I just wanted to confirm that using a straight number vs sizeof had the same effect therefore my reasoning of clearing more than the size is most likely true. I'll know in a few minutes, I'm almost done.
Does it make any sense?
Thanks!
Ben |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 14, 2020 9:41 pm |
|
|
sizeof() gives the size in bytes. If your array is declared as int16 and
has a size of 20 elements, then sizeof() will report 40 as the size.
It's way better to use sizeof() in your code. Then if you change the size
of the array in the declaration, your code will automatically get the change
when it does sizeof(). |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Dec 14, 2020 10:33 pm |
|
|
Ok then so the general rule here is to use sizeof() no matter what, when using memset(), correct?
This would explain now why all my code is back to working again after I've re-changed all the direct size values to sizeof().
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Dec 15, 2020 2:08 am |
|
|
It's worth realising that the 'sizeof' value is solved at compile time, so it
costs nothing to use sizeof, rather than manually coding a size. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1358
|
|
Posted: Tue Dec 15, 2020 2:24 pm |
|
|
Just be aware that if you use sizeof() on a pointer rather than an actual array, then it will give the size of the pointer instead of the array:
Code: |
void test(char * MyString){
memset( MyString, NULL, sizeof( MyString )); // OOF! returns size of a pointer
}
|
vs
Code: |
void test(){
char MyString[] = "hello there";
memset( MyString, NULL, sizeof( MyString )); // OK! returns size of the array
}
|
|
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Wed Dec 16, 2020 9:49 am |
|
|
Hi Jeremiah,
I think that's where I got confused.... if I use your example:
Code: |
void test(char * MyString)
{
memset( MyString, NULL, sizeof( MyString ));
}
|
In this example, what is the best approach then to clear the entire string? Should the function pass the length of the string the use the length instead?
Code: |
void test(char * MyString, unsigned int8 Length)
{
memset( MyString, NULL, Length );
}
|
Thanks,
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Dec 16, 2020 10:48 am |
|
|
Strings in C do not have a size.
They only have a size when initialised, which is why sizeof can then
tell you how large they are.
When a pointer is passed to a function all size knowledge is lost. It
is just a pointer. You can detect how long the actual 'string' contained
is, using strlen, but to overwrite an entire buffer, the size of the buffer
itself has to actually be passed to the function.
<https://stackoverflow.com/questions/609267/passing-char-buffer-to-functions-and-getting-the-size-of-the-buffer> |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Thu Dec 17, 2020 7:29 am |
|
|
Thanks all. This I guess leads to two more questions then.... PCM Programmer stated the following:
sizeof() gives the size in bytes. If your array is declared as int16 and
has a size of 20 elements, then sizeof() will report 40 as the size.
1) So in general in my case, everytime I pass a string to a function, it's always an unsigned char *String. I've read in another post something about byte boundaries and what not. I guess this would not apply to single bytes but rather anything above a 16-bit value?
2) Then I can take for granted that if I do this it will always work?:
Code: | void MyFunction( unsigned char *String, unsigned int8 Length )
{
memset( String, NULL, Length );
}
|
I just want to make sure that when I call a function and pass it a string with the length, it will always clear the entire string, not just a part of it and not exceed the memory space and overwrite something else in the code and crash the MCU.
I know it sounds odd and trivial as a question but I believe that the CCS compiler and how it works internally is different than a traditional C compiler on a PC.
Thanks again!
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Dec 17, 2020 1:37 pm |
|
|
No, in this CCS is completely standard. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Thu Dec 17, 2020 2:05 pm |
|
|
Fair enough! Thanks for all the help!
Ben |
|
|
|