Passing an array as argument to a function
-
Right you are! I forget to remove the
*
.Robust Services Core | Software Techniques for Lemmings | Articles
-
thanks Greg for that tip
I made a mistake. See Richard's post below.
Robust Services Core | Software Techniques for Lemmings | Articles
-
I made a mistake. See Richard's post below.
Robust Services Core | Software Techniques for Lemmings | Articles
noticed
-
Right you are! I forget to remove the
*
.Robust Services Core | Software Techniques for Lemmings | Articles
-
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 beingif(p)
, for which I writeif(p != nullptr)
.Robust Services Core | Software Techniques for Lemmings | Articles
-
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 beingif(p)
, for which I writeif(p != nullptr)
.Robust Services Core | Software Techniques for Lemmings | Articles
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. -
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...Robust Services Core | Software Techniques for Lemmings | Articles
-
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:
f you want to pass a single int, char etc, then why use a pointer?
On occasion you want an "out" or sentinel parameter, so in those cases you have to use a pointer (or a reference if using C++). There's lots of cases where you might have a pointer to a single struct that you either want to fill in, or avoid copying the whole thing to the stack. For the latter, of course, you'd mark it as
const
.Keep Calm and Carry On
-
how do you declare and access an array of pointers? if you want to cycle through pointers of same type in a for loop.
int * somedata[] = new int * [5]; ??
"DreamLand Page" on facebook
-
how do you declare and access an array of pointers? if you want to cycle through pointers of same type in a for loop.
int * somedata[] = new int * [5]; ??
"DreamLand Page" on facebook
In that case you'd use another level of indirection: e.g.
#include <iostream>
void myfn(int **data, size_t len)
{
for(size_t i = 0; i < len; ++i)
*data[i] = i * 2; // assign value to address pointed to by data[i]// alternatively : // for(size\_t i = 0; i < len; ++i) // \*\*data++ = i\*2; // Note: use double de-reference and post increment!
}
int main)_
{
int data[5] = { 1, 2, 3, 4, 5 }; // our original data
const size_t ndata = sizeof(data)/sizeof(data[0]);
int** pdata = new int*[ndata]; // double indirection used for definition of pdata// assign each element of pdata the address of element of data for(size\_t i = 0; i < ndata; ++i) pdata\[i\] = &data\[i\]; // or could use pdata\[i\] = data+i; std::cout << "Before:\\n"; for(size\_t i = 0; i < ndata; ++i) std::cout <^lt; \*pdata\[i\] << std::endl; myfn(pdata, 5); std::cout <\*lt; "\\nAfter:\\n"; for(size\_t i = 0; i < ndata; ++i) std::cout << \*pdata\[i\] << std::endl; delete\[\] pdata; return 0;
}
Keep Calm and Carry On
-
how do you declare and access an array of pointers? if you want to cycle through pointers of same type in a for loop.
int * somedata[] = new int * [5]; ??
"DreamLand Page" on facebook
-
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
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]))
#endifIn vino veritas
-
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...Robust Services Core | Software Techniques for Lemmings | Articles
-
It's true that C++ has no explicit notion of a null reference. But if you run this
void test(int& i)
{
if(i == 1)
std::cout << i << '\n';
}int main(int argc, char* argv[])
{
int* pi = nullptr;
test(*pi);
}it will
SIGSEGV
on the lineif(i == 1)
. That's in a VS2017 debug build.Robust Services Core | Software Techniques for Lemmings | Articles
-
It's true that C++ has no explicit notion of a null reference. But if you run this
void test(int& i)
{
if(i == 1)
std::cout << i << '\n';
}int main(int argc, char* argv[])
{
int* pi = nullptr;
test(*pi);
}it will
SIGSEGV
on the lineif(i == 1)
. That's in a VS2017 debug build.Robust Services Core | Software Techniques for Lemmings | Articles
-
That is interesting. It should really crash at the
test(*pi);
line, since it is trying to dereference a null pointer. I would also suggest the the compiler should recognise thatpi
is a pointer and not a reference.I agree that it should crash there. But I've never seen it work that way, though for most of my career I worked in a language where it would have crashed there. It's not unusual to dereference a pointer (
pi
) and pass it to an argument that wants a reference.Robust Services Core | Software Techniques for Lemmings | Articles
-
I agree that it should crash there. But I've never seen it work that way, though for most of my career I worked in a language where it would have crashed there. It's not unusual to dereference a pointer (
pi
) and pass it to an argument that wants a reference.Robust Services Core | Software Techniques for Lemmings | Articles
-
Greg Utas wrote:
It's not unusual ...
Interesting, but not something I have ever done. I had (naively) assumed that the whole point of references was to avoid this very trap. Incidentally I tried it in g++ as well and the gave a SEGV.
Where did it die in g++? Before or after calling the function?
Robust Services Core | Software Techniques for Lemmings | Articles
-
Where did it die in g++? Before or after calling the function?
Robust Services Core | Software Techniques for Lemmings | Articles