|
@Richard Meh I`m really not doing anything worth much attention. My code is stashed with hacks so I`m just trying to fix on it.
"DreamLand Page" on facebook
|
|
|
|
|
fearless_ wrote: My code is stashed with hacks So it all needs a lot of attention.
|
|
|
|
|
Thanks for pointing how things are meant to be done Richard
"DreamLand Page" on facebook
|
|
|
|
|
Further to what Richard has said, you could also do some defensive programming by passing in the length of the array. eg:
void myFunc(int* somedata, size_t data_len)
{
for(size_t i = 0; i < data_len; ++i)
somedata[i] *= 2;
return;
}
int myArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
const size_t arrLen = sizeof(myArray)/sizeof(myArray[0]);
myFunc(myArray), arrLen);
This will prevent data overflows, and/or segfaults, when accessing myArray inside the function.
Things to note:
* we can get the compiler to tell us how many elements in the array using the sizeof(myArray)/sizeof(myArray[0]) construct. This is calculated at compile time and in release mode, in most cases it will be optimized out, so it does not add to your memory usage, if that's a concern.
* Using the constant arrLen means that if we change the number of elements in myArray, we don't need to go through the code and find all uses of myArray and make sure we're passing in the right number
* If we had used arrLen = sizeof(myArray)/sizeof(int) , we need to remember to change the definition of arrLen if we change the type of myArray . Using sizeof(myArray[0] mean that if we change the type of myArray from int[] to double[] , for example, we don't need to remember to change the definition of arrLen as well
Keep Calm and Carry On
|
|
|
|
|
There is also the _countof() macro, which gives the number of elements in arrays of any simple or composite type.
|
|
|
|
|
Best macro ever added into C standard ... wish more people would use it.
In vino veritas
|
|
|
|
|
They probably would if it was easier to find; after all it is in the documentation. 
|
|
|
|
|
I didn't know about _countof() . Is it an MS only extension? Trying to compile with gcc under linux produces an implicit declaration warning in C and a not declared in this scope in C++
Keep Calm and Carry On
|
|
|
|
|
|
The leading '_' indicates it's a system level macro, i. e. Windows specific.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
|
As it is a macro it's easy to test for and if not there simply use a copy of the macro
#if !defined(_countof)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif
In vino veritas
|
|
|
|
|
You can write it like this
void myFunc(char somedata[]) to highlight that it's actually an array rather than just a pointer to a single char . Given that it's an array, its size is often provided to avoid the kind of trampling that you pointed out:
void myFunc(char somedata[], size_t n)
modified 29-Mar-20 12:26pm.
|
|
|
|
|
|
Under C any pointer is already a pointer to an array it's built into the language along with pointer arithmetic ... you need to just learn that.
Literally declare any pointer of anything lets do a float
float* p;
now you can access it as an array
p[0] = 5.0;
p[100] = 10.0;
It will crash because the pointer isn't really to any memory but it makes the point the pointer is already a pointer to an array
There are no exceptions to the rule it doesn't matter if the pointer is to a fundamental type or struct .... so I don't get how you could ever forget that. In the C community the [] use is rare because it's two extra characters to type. It also has implication when declaring variables because it puts that array on the stack not on data memory or constant memory (rodata) if it determines its a constant. So if you get into the habit of using that form you can get some undesirable things happen.
Personally you are learning and I would learn to live without it and just learn them as you will most often see them written.
The topic is well covered in dummies guide to C but you will note the last statement
How to Use Arrays and Functions Together in C Programming - dummies[^]
In vino veritas
|
|
|
|
|
I made a mistake. See Richard's post below.
|
|
|
|
|
noticed
modified 29-Mar-20 12:16pm.
|
|
|
|
|
Greg Utas wrote: char* somedata[] That's an array of pointers.
|
|
|
|
|
good pick didn't even notice the * because that form is so foreign to me.
In vino veritas
|
|
|
|
|
Right you are! I forget to remove the * .
|
|
|
|
|
Why not leave the * but remove the [] ? The parameter is a pointer to an array, not an actual array.
|
|
|
|
|
I use brackets to indicate that the underlying is an array, not a pointer to a single char . Maybe it's because I was a latecomer to C++ and never used C idioms, another one being if(p) , for which I write if(p != nullptr) .
|
|
|
|
|
A pointer rarely means a pointer to a single item, it always indicates a pointer to a set of items. If you want to pass a single int, char etc, then why use a pointer?
I would agree with you on using the if(p != nullptr) construct, it makes it much clearer.
|
|
|
|
|
Richard MacCutchan wrote: If you want to pass a single int, char etc, then why use a pointer? Because it might inadvertently be nullptr , and I find this defensive code jarring:
void f(type& t)
{
if(&t ! nullptr)...
} The optimize-everything crowd won't agree, but in my opinion code that invokes the above with a null reference should suffer a SIGSEGV before the function is called. But since that's not the case...
|
|
|
|
|
I don't think a reference can ever be null.
|
|
|
|