Base types and pointer arrays
-
I'm trying to create an array of pointers to a common base class, but each pointer in the array will point to a different derived class instance. This is a 64-bit application. Here's the critical portion of my code: (Unnecessary detail has been removed.) Intellisense is warning me that the second pointer assignment (to the second element in the array) will cause a buffer overrun. It says,
"C6386: Buffer overrun while writing to 'this->m_Members': the writable size is 'this->m_MemberCount*8' bytes, but '16' bytes might be written."
I have never come across this warning before, and I wanted to ask the community if there is something obviously wrong with the code that I'm not seeing.m\_MemberCount = 7; CGsUCharType\* m\_s\_b1 = new CGsUCharType(); // All of these "Type" classes are derived from CGsTypeBase CGsUCharType\* m\_s\_b2 = new CGsUCharType(); CGsUCharType\* m\_s\_b3 = new CGsUCharType(); CGsUCharType\* m\_s\_b4 = new CGsUCharType(); CGsUShortType\* m\_s\_w1 = new CGsUShortType(); CGsUShortType\* m\_s\_w2 = new CGsUShortType(); CGsULongType\* m\_S\_addr = new CGsULongType(); CGsTypeBase\*\* m\_Members = new CGsTypeBase\*\[m\_MemberCount\]; // Is this the correct way to create an array of pointers? m\_Members\[0\] = m\_s\_b1; m\_Members\[1\] = m\_s\_b2; // This line has the warning about the buffer overrun. m\_Members\[2\] = m\_s\_b3; m\_Members\[3\] = m\_s\_b4; m\_Members\[4\] = m\_s\_w1; m\_Members\[5\] = m\_s\_w2; m\_Members\[6\] = m\_S\_addr;
The difficult we do right away... ...the impossible takes slightly longer.
-
I'm trying to create an array of pointers to a common base class, but each pointer in the array will point to a different derived class instance. This is a 64-bit application. Here's the critical portion of my code: (Unnecessary detail has been removed.) Intellisense is warning me that the second pointer assignment (to the second element in the array) will cause a buffer overrun. It says,
"C6386: Buffer overrun while writing to 'this->m_Members': the writable size is 'this->m_MemberCount*8' bytes, but '16' bytes might be written."
I have never come across this warning before, and I wanted to ask the community if there is something obviously wrong with the code that I'm not seeing.m\_MemberCount = 7; CGsUCharType\* m\_s\_b1 = new CGsUCharType(); // All of these "Type" classes are derived from CGsTypeBase CGsUCharType\* m\_s\_b2 = new CGsUCharType(); CGsUCharType\* m\_s\_b3 = new CGsUCharType(); CGsUCharType\* m\_s\_b4 = new CGsUCharType(); CGsUShortType\* m\_s\_w1 = new CGsUShortType(); CGsUShortType\* m\_s\_w2 = new CGsUShortType(); CGsULongType\* m\_S\_addr = new CGsULongType(); CGsTypeBase\*\* m\_Members = new CGsTypeBase\*\[m\_MemberCount\]; // Is this the correct way to create an array of pointers? m\_Members\[0\] = m\_s\_b1; m\_Members\[1\] = m\_s\_b2; // This line has the warning about the buffer overrun. m\_Members\[2\] = m\_s\_b3; m\_Members\[3\] = m\_s\_b4; m\_Members\[4\] = m\_s\_w1; m\_Members\[5\] = m\_s\_w2; m\_Members\[6\] = m\_S\_addr;
The difficult we do right away... ...the impossible takes slightly longer.
Your code should work (Intellisense is a little confused here), but may I suggest using std::vector instead:
#include <vector>
...std::vector<CGsTypeBase*> m_Members(m_MemberCount);
This will ensure that your array is properly constructed and is destructed when it goes out of scope. You may also wish to look into storing smart pointers (rather than raw pointers) in the vector. This can help ensure that they are destructed at the right time, as well.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.
-
I'm trying to create an array of pointers to a common base class, but each pointer in the array will point to a different derived class instance. This is a 64-bit application. Here's the critical portion of my code: (Unnecessary detail has been removed.) Intellisense is warning me that the second pointer assignment (to the second element in the array) will cause a buffer overrun. It says,
"C6386: Buffer overrun while writing to 'this->m_Members': the writable size is 'this->m_MemberCount*8' bytes, but '16' bytes might be written."
I have never come across this warning before, and I wanted to ask the community if there is something obviously wrong with the code that I'm not seeing.m\_MemberCount = 7; CGsUCharType\* m\_s\_b1 = new CGsUCharType(); // All of these "Type" classes are derived from CGsTypeBase CGsUCharType\* m\_s\_b2 = new CGsUCharType(); CGsUCharType\* m\_s\_b3 = new CGsUCharType(); CGsUCharType\* m\_s\_b4 = new CGsUCharType(); CGsUShortType\* m\_s\_w1 = new CGsUShortType(); CGsUShortType\* m\_s\_w2 = new CGsUShortType(); CGsULongType\* m\_S\_addr = new CGsULongType(); CGsTypeBase\*\* m\_Members = new CGsTypeBase\*\[m\_MemberCount\]; // Is this the correct way to create an array of pointers? m\_Members\[0\] = m\_s\_b1; m\_Members\[1\] = m\_s\_b2; // This line has the warning about the buffer overrun. m\_Members\[2\] = m\_s\_b3; m\_Members\[3\] = m\_s\_b4; m\_Members\[4\] = m\_s\_w1; m\_Members\[5\] = m\_s\_w2; m\_Members\[6\] = m\_S\_addr;
The difficult we do right away... ...the impossible takes slightly longer.
What are the definitions of
CGsTypeBase
andCGsUCharType
? [edit] I built this short program and it compiled and linked successfully:struct CGsTypeBase
{
char foo[8];
};
struct CGsUCharType : CGsTypeBase
{
wchar_t foo[8];
};struct CGsUShortType : CGsTypeBase
{
uint16_t foo[8];
};
struct CGsULongType : CGsTypeBase
{
long foo[8];
};int main(
int argc,
char* argv[]
)
{
int m_MemberCount = 7;CGsUCharType\* m\_s\_b1 = new CGsUCharType(); // All of these "Type" classes are derived from CGsTypeBase CGsUCharType\* m\_s\_b2 = new CGsUCharType(); CGsUCharType\* m\_s\_b3 = new CGsUCharType(); CGsUCharType\* m\_s\_b4 = new CGsUCharType(); CGsUShortType\* m\_s\_w1 = new CGsUShortType(); CGsUShortType\* m\_s\_w2 = new CGsUShortType(); CGsULongType\* m\_S\_addr = new CGsULongType(); CGsTypeBase\*\* m\_Members = new CGsTypeBase\*\[m\_MemberCount\]; // Yes, this is the correct way to create an array of pointers m\_Members\[0\] = m\_s\_b1; m\_Members\[1\] = m\_s\_b2; // No warnings here m\_Members\[2\] = m\_s\_b3; m\_Members\[3\] = m\_s\_b4; m\_Members\[4\] = m\_s\_w1; m\_Members\[5\] = m\_s\_w2; m\_Members\[6\] = m\_S\_addr; return 0;
}
So how does that differ from your code? [/edit]
-
I'm trying to create an array of pointers to a common base class, but each pointer in the array will point to a different derived class instance. This is a 64-bit application. Here's the critical portion of my code: (Unnecessary detail has been removed.) Intellisense is warning me that the second pointer assignment (to the second element in the array) will cause a buffer overrun. It says,
"C6386: Buffer overrun while writing to 'this->m_Members': the writable size is 'this->m_MemberCount*8' bytes, but '16' bytes might be written."
I have never come across this warning before, and I wanted to ask the community if there is something obviously wrong with the code that I'm not seeing.m\_MemberCount = 7; CGsUCharType\* m\_s\_b1 = new CGsUCharType(); // All of these "Type" classes are derived from CGsTypeBase CGsUCharType\* m\_s\_b2 = new CGsUCharType(); CGsUCharType\* m\_s\_b3 = new CGsUCharType(); CGsUCharType\* m\_s\_b4 = new CGsUCharType(); CGsUShortType\* m\_s\_w1 = new CGsUShortType(); CGsUShortType\* m\_s\_w2 = new CGsUShortType(); CGsULongType\* m\_S\_addr = new CGsULongType(); CGsTypeBase\*\* m\_Members = new CGsTypeBase\*\[m\_MemberCount\]; // Is this the correct way to create an array of pointers? m\_Members\[0\] = m\_s\_b1; m\_Members\[1\] = m\_s\_b2; // This line has the warning about the buffer overrun. m\_Members\[2\] = m\_s\_b3; m\_Members\[3\] = m\_s\_b4; m\_Members\[4\] = m\_s\_w1; m\_Members\[5\] = m\_s\_w2; m\_Members\[6\] = m\_S\_addr;
The difficult we do right away... ...the impossible takes slightly longer.
-
Your code should work (Intellisense is a little confused here), but may I suggest using std::vector instead:
#include <vector>
...std::vector<CGsTypeBase*> m_Members(m_MemberCount);
This will ensure that your array is properly constructed and is destructed when it goes out of scope. You may also wish to look into storing smart pointers (rather than raw pointers) in the vector. This can help ensure that they are destructed at the right time, as well.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.
Thank you for taking the time to respond. I will consider using vector instead.
The difficult we do right away... ...the impossible takes slightly longer.
-
What are the definitions of
CGsTypeBase
andCGsUCharType
? [edit] I built this short program and it compiled and linked successfully:struct CGsTypeBase
{
char foo[8];
};
struct CGsUCharType : CGsTypeBase
{
wchar_t foo[8];
};struct CGsUShortType : CGsTypeBase
{
uint16_t foo[8];
};
struct CGsULongType : CGsTypeBase
{
long foo[8];
};int main(
int argc,
char* argv[]
)
{
int m_MemberCount = 7;CGsUCharType\* m\_s\_b1 = new CGsUCharType(); // All of these "Type" classes are derived from CGsTypeBase CGsUCharType\* m\_s\_b2 = new CGsUCharType(); CGsUCharType\* m\_s\_b3 = new CGsUCharType(); CGsUCharType\* m\_s\_b4 = new CGsUCharType(); CGsUShortType\* m\_s\_w1 = new CGsUShortType(); CGsUShortType\* m\_s\_w2 = new CGsUShortType(); CGsULongType\* m\_S\_addr = new CGsULongType(); CGsTypeBase\*\* m\_Members = new CGsTypeBase\*\[m\_MemberCount\]; // Yes, this is the correct way to create an array of pointers m\_Members\[0\] = m\_s\_b1; m\_Members\[1\] = m\_s\_b2; // No warnings here m\_Members\[2\] = m\_s\_b3; m\_Members\[3\] = m\_s\_b4; m\_Members\[4\] = m\_s\_w1; m\_Members\[5\] = m\_s\_w2; m\_Members\[6\] = m\_S\_addr; return 0;
}
So how does that differ from your code? [/edit]
Yes, my code compiles and links successfully too. I guess it's just intellisense that has a problem. Thank you for your response.
The difficult we do right away... ...the impossible takes slightly longer.
-
A wild guess: the intellisense does not think (like, instead, you assume) that
m_MemberCount
is equal to7
."In testa che avete, Signor di Ceprano?" -- Rigoletto
That's what I think as well. I'm glad to know someone else has the same idea. I did come across a few posts about that warning being incorrect.
The difficult we do right away... ...the impossible takes slightly longer.
-
I'm trying to create an array of pointers to a common base class, but each pointer in the array will point to a different derived class instance. This is a 64-bit application. Here's the critical portion of my code: (Unnecessary detail has been removed.) Intellisense is warning me that the second pointer assignment (to the second element in the array) will cause a buffer overrun. It says,
"C6386: Buffer overrun while writing to 'this->m_Members': the writable size is 'this->m_MemberCount*8' bytes, but '16' bytes might be written."
I have never come across this warning before, and I wanted to ask the community if there is something obviously wrong with the code that I'm not seeing.m\_MemberCount = 7; CGsUCharType\* m\_s\_b1 = new CGsUCharType(); // All of these "Type" classes are derived from CGsTypeBase CGsUCharType\* m\_s\_b2 = new CGsUCharType(); CGsUCharType\* m\_s\_b3 = new CGsUCharType(); CGsUCharType\* m\_s\_b4 = new CGsUCharType(); CGsUShortType\* m\_s\_w1 = new CGsUShortType(); CGsUShortType\* m\_s\_w2 = new CGsUShortType(); CGsULongType\* m\_S\_addr = new CGsULongType(); CGsTypeBase\*\* m\_Members = new CGsTypeBase\*\[m\_MemberCount\]; // Is this the correct way to create an array of pointers? m\_Members\[0\] = m\_s\_b1; m\_Members\[1\] = m\_s\_b2; // This line has the warning about the buffer overrun. m\_Members\[2\] = m\_s\_b3; m\_Members\[3\] = m\_s\_b4; m\_Members\[4\] = m\_s\_w1; m\_Members\[5\] = m\_s\_w2; m\_Members\[6\] = m\_S\_addr;
The difficult we do right away... ...the impossible takes slightly longer.
Richard Andrew x64 wrote:
CGsTypeBase** m_Members = new CGsTypeBase*[m_MemberCount]; // Is this the correct way to create an array of pointers?
As others have pointed out the your solution works because of the way the memory lays down. In the above you have a declaration of a variable which has a type. And you also give the variable a value. But the declaration of the variable is a pointer. Just a pointer. Not a pointer to an array. So when intellisense sees you use it as an array it goes basically 'pointer + 1' isn't going to work. It does works because of the value and not the declaration. I believe there is a declaration form that allows you to specify the form that would make intellisense happy but been a long time since I attempted C++ so I will leave it to someone else to come up with the form that makes the array specific.
-
Richard Andrew x64 wrote:
CGsTypeBase** m_Members = new CGsTypeBase*[m_MemberCount]; // Is this the correct way to create an array of pointers?
As others have pointed out the your solution works because of the way the memory lays down. In the above you have a declaration of a variable which has a type. And you also give the variable a value. But the declaration of the variable is a pointer. Just a pointer. Not a pointer to an array. So when intellisense sees you use it as an array it goes basically 'pointer + 1' isn't going to work. It does works because of the value and not the declaration. I believe there is a declaration form that allows you to specify the form that would make intellisense happy but been a long time since I attempted C++ so I will leave it to someone else to come up with the form that makes the array specific.
Thanks for your input. I appreciate you taking the time to post.
The difficult we do right away... ...the impossible takes slightly longer.