does a function know how much memory its parameters occupy?
When we call function passing by value, we are making a copy in memory of the actual parameters' value.
The question is: does the function know how much space its parameters occupy in memory? If the answers is yes, how we can retrieve it in function scope?
If the answers in no, do we have a potentially hidden memory error?
consider this example:
#include <stdio.h>
void func(char * X)
{
X +=98;
*X='C'; //is this really OK? or we have hidden memory error?
*++X='\0';
--X;
puts(X); }
int main()
{
char A[100];
char *B =A;
func(B);
return 0;
}
Re: does a function know how much memory its parameters occupy?
Quote:
Originally Posted by alwaystudent
The question is: does the function know how much space its parameters occupy in memory?
Yes, at least insofar as a construct like a function can "know" something.
Quote:
Originally Posted by alwaystudent
If the answers is yes, how we can retrieve it in function scope?
You can use the sizeof operator to determine the sizes of the various parameters.
Quote:
Originally Posted by alwaystudent
*X='C'; //is this really OK? or we have hidden memory error?
It is OK as long as the previous line does not cause the pointer to point beyond the boundary of the array.
However, this is an entirely different thing from "how much space its parameters occupy in memory": the pointer is a parameter, but the object (that is an element of an array) that the pointer points to is not a parameter. sizeof(X) will give you the size of the pointer, sizeof(*X) will give you the size of what the pointer points to, but neither of these is the size of the array.
Hence, you should have another parameter for the size of the array, or pass two pointers (the start and one-past-the-end of the range), or pass a std::array or some other container, or designate a special value to mark the end of the array (as in null terminated strings, but note that this tends to be error prone).
Re: does a function know how much memory its parameters occupy?
If that(*X='C') is OK and we do not have potentially error when derefrencing pointer X, after shift +98, it means in function scope , we(machine) know how much memory allocated to X or we(machine) know -in function scope- boundary of X, but how to retrieve it in function scope?
Re: does a function know how much memory its parameters occupy?
Quote:
Originally Posted by alwaystudent
If that(*X='C') is OK and we do not have potentially error when derefrencing pointer X, after shift +98
No, the lack of an obvious error like a crash does not mean that *X is okay. If the array had fewer than 99 elements, *X would have resulted in undefined behaviour.
Quote:
Originally Posted by alwaystudent
it means in function scope , we(machine) know how much memory allocated to X or we(machine) know -in function scope- boundary of X, but how to retrieve it in function scope?
I already told you: pass the size as an argument, etc. There is no way in standard C or standard C++ to retrieve the size of the array given just a pointer to an element in the array.
Re: does a function know how much memory its parameters occupy?
@laserlight thank you, i think i got the point!
Re: does a function know how much memory its parameters occupy?
Quote:
There is no way in standard C or standard C++ to retrieve the size of the array given just a pointer to an element in the array.
There are, however, non-standard ways of determining this, depending upon the compiler, which aren't portable. Have a look at your compiler documentation. eg for Microsoft VS there is _msize(). See https://msdn.microsoft.com/en-us/lib...vs.120%29.aspx
Re: does a function know how much memory its parameters occupy?
Quote:
Originally Posted by
2kaud
@2kaud, thank you so much, but it work, as I test, for heap, not for stack, is there another function that works for stack?
Re: does a function know how much memory its parameters occupy?
The above answers are correct.
however.
it is better to design your code in such a way to void the issue entirely. Functions (or class members) that expose pointers are 'flawed' because the meaning is always going to be dubious unless you know what the function does internally.
does b point to a single bar ? to an array of bar ? if an array, how large is it allowed to be (or required to be) ? can I pass a NULL ?
functions that return pointers get additional problems. are we to delete the pointer ? or is that take care of otherwise ? is it a delete or a delete[] ?...
So if you are writing new code, avoid the issue entirely by writting better code that doesn't expose pointers. You'll save yourself a lot of headaches, and the people that will need to maintian the software after you will thank you for it too.
if it's a single element, use a reference instead of a pointer
if it's an array. Use a container, and pass a reference to the container (sample for vector, could be any specific container you want)
Code:
void foo(std::vector<bar>& v)
or even better, pass a begin and end iterator, your function will then work with 'any' container that supports the iterators your algorithm needs (there are different types of iterators). This is the best way to making algorithms that are easier to use and re-use.
Code:
template <class iter>
void foo(iter begin, iter end)
If the code can't be put into a header for some reason, you can prototype this for one specific type of iterator. But then it'll only be available for use with that iterator type. The above has the beauty it also works with regular arrays.
Re: does a function know how much memory its parameters occupy?
Quote:
Originally Posted by
OReubens
The above answers are correct.
however.
it is better to design your code in such a way to void the issue entirely. Functions (or class members) that expose pointers are 'flawed' because the meaning is always going to be dubious unless you know what the function does internally.
does b point to a single bar ? to an array of bar ? if an array, how large is it allowed to be (or required to be) ? can I pass a NULL ?
functions that return pointers get additional problems. are we to delete the pointer ? or is that take care of otherwise ? is it a delete or a delete[] ?...
So if you are writing new code, avoid the issue entirely by writting better code that doesn't expose pointers. You'll save yourself a lot of headaches, and the people that will need to maintian the software after you will thank you for it too.
if it's a single element, use a reference instead of a pointer
if it's an array. Use a container, and pass a reference to the container (sample for vector, could be any specific container you want)
Code:
void foo(std::vector<bar>& v)
or even better, pass a begin and end iterator, your function will then work with 'any' container that supports the iterators your algorithm needs (there are different types of iterators). This is the best way to making algorithms that are easier to use and re-use.
Code:
template <class iter>
void foo(iter begin, iter end)
If the code can't be put into a header for some reason, you can prototype this for one specific type of iterator. But then it'll only be available for use with that iterator type. The above has the beauty it also works with regular arrays.
@OReubens: Thank you for good explanation with C++ style,
Re: does a function know how much memory its parameters occupy?
Note: In this case, It is possible to increase your stacksize in your project, not that you should really ever have to. The example was pretty static.
Re: does a function know how much memory its parameters occupy?
If you are using a fixed length C array it can also be implemented in this way.
Where 'N' is the size of the array.
Be aware of course that each unique combination of T & N will create a another version of 'foo'. This may lead to code bloat if not used carefully.
Code:
template <typename T, std::size_t N>
void foo( T (&array)[N] )
{
for (size_t i = 0; i < N; ++i)
{
// Do something with array[i]
}
}