|
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.
|
|
|
|
|
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 line if(i == 1) . That's in a VS2017 debug build.
|
|
|
|
|
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 that pi 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.
|
|
|
|
|
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?
|
|
|
|
|
Same as in Windows, on the if statement in test function.
|
|
|
|
|
Ditto for clang 9.0.1 (Fedora fc31)
Keep Calm and Carry On
|
|
|
|
|
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
modified 29-Mar-20 14:42pm.
|
|
|
|
|
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;
}
int main)_
{
int data[5] = { 1, 2, 3, 4, 5 }; const size_t ndata = sizeof(data)/sizeof(data[0]);
int** pdata = new int*[ndata];
for(size_t i = 0; i < ndata; ++i)
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
modified 29-Mar-20 17:49pm.
|
|
|
|
|
|
This array of pointers thing is above trivial. Here is my old code:
CUSTOMVERTEX* ScreenLetters;
ScreenTextBuffers[0]->Lock( 0, 0, (void**)&ScreenLetters, 0 );
int LetterVertexDataincrement = 0;
int letterwidth = 12;
int letterheight = 12;
for(int ii = 0; ii < ScreenLetterGroups[0].height;ii++)
{
for(int i = 0; i < ScreenLetterGroups[0].width;i++)
{
ScreenLetters[LetterVertexDataincrement].position.x = i * letterwidth + ScreenLetterGroups[0].x;
ScreenLetters[LetterVertexDataincrement].position.y = ii * letterheight + ScreenLetterGroups[0].y;
ScreenLetters[LetterVertexDataincrement].position.z = 20;
ScreenLetters[LetterVertexDataincrement].color = 0xffffffff;
}
}
ScreenTextBuffers[0]->Unlock();
I have this piece of code repeating for every ScreenTextBuffers element. I want to place it in a `for` loop so what I`m doing is:
CUSTOMVERTEX ** ScreenLettersP_s = new CUSTOMVERTEX* [NumberOfTextBuffers];
int LetterVertexDataincrement = 0;
int letterwidth = 12;
int letterheight = 12;
for(int iii =0; iii < NumberOfTextBuffers; iii++)
{
ScreenTextBuffers[iii]->Lock( 0, 0, (void**)&ScreenLettersP_s[iii], 0 );
for(int ii = 0; ii < ScreenLetterGroups[iii].height;ii++)
{
for(int i = 0; i < ScreenLetterGroups[iii].width;i++)
{
*ScreenLettersP_s[LetterVertexDataincrement]->position.x = i * letterwidth + ScreenLetterGroups[iii].x;
*ScreenLettersP_s[LetterVertexDataincrement]->position.y = ii * letterheight + ScreenLetterGroups[iii].y;
*ScreenLettersP_s[LetterVertexDataincrement]->position.z = 20;
*ScreenLettersP_s[LetterVertexDataincrement]->color = 0xffffffff;
}
}
ScreenTextBuffers[i]->Unlock();
}
but it doesn`t compile, I`m getting an `illegal indirection` error
struct CUSTOMVERTEX
{
D3DXVECTOR3 position;
D3DCOLOR color;
FLOAT tu, tv;
};
modified 1-Apr-20 6:03am.
|
|
|
|
|
Arrays of pointers are just as trivial as arrays of anything, if you understand how to address them.
fearless_ wrote: I`m getting an `illegal indirection` error Since we cannot see your screen we also cannot guess where that occurs. Please format your code properly and explain exactly where the error occurs.
|
|
|
|
|
I get illegal indirection at this spot
*ScreenLettersP_s[LetterVertexDataincrement]->position.x = i * letterwidth + ScreenLetterGroups[i].x
|
|
|
|
|
The variable ScreenLettersP_s is an array of pointers, so the reference ScreenLettersP_s[LetterVertexDataincrement] is one of the actual pointers. The leading asterisk on ScreenLettersP_s means an extra level of indirection which is not required (or valid).
|
|
|
|