the momory leak
-
Good afternoon, the app detected memory leak at this point: Groups = new GROUPSTRUCT[NumberofGroups]; for ( i = 0; i < NumberofGroups; i++ ) { Discount->GetGroup( Groups[i].GroupID ); Groups[i].TotalContributory = 0.0; } and here is the delete: if ( Groups ) { delete[] Groups; Groups = NULL; } NumberofGroups = this->GetContributoryAmounts (mainPos); for ( i = 0; i < NumberofGroups; i++ ) { DiscountData->GroupID = Groups[i].GroupID; DiscountData->TotalContributory = Groups[i].TotalContributory; Is this the proper delete? thanks!
-
Good afternoon, the app detected memory leak at this point: Groups = new GROUPSTRUCT[NumberofGroups]; for ( i = 0; i < NumberofGroups; i++ ) { Discount->GetGroup( Groups[i].GroupID ); Groups[i].TotalContributory = 0.0; } and here is the delete: if ( Groups ) { delete[] Groups; Groups = NULL; } NumberofGroups = this->GetContributoryAmounts (mainPos); for ( i = 0; i < NumberofGroups; i++ ) { DiscountData->GroupID = Groups[i].GroupID; DiscountData->TotalContributory = Groups[i].TotalContributory; Is this the proper delete? thanks!
valerie99 wrote:
Is this the proper delete?
Yes, except you don't need to check if
Groups
is not null, before deleting. IfGroups
is null thendelete
simply does nothing. My question is: Are you realy trying to accessGroups
after deleting them.DiscountData->GroupID = Groups[i].GroupID;
INTP Every thing is relative... -
Good afternoon, the app detected memory leak at this point: Groups = new GROUPSTRUCT[NumberofGroups]; for ( i = 0; i < NumberofGroups; i++ ) { Discount->GetGroup( Groups[i].GroupID ); Groups[i].TotalContributory = 0.0; } and here is the delete: if ( Groups ) { delete[] Groups; Groups = NULL; } NumberofGroups = this->GetContributoryAmounts (mainPos); for ( i = 0; i < NumberofGroups; i++ ) { DiscountData->GroupID = Groups[i].GroupID; DiscountData->TotalContributory = Groups[i].TotalContributory; Is this the proper delete? thanks!
valerie99 wrote:
the app detected memory leak at this point:
Clicking on the line in the Debug window should take you to the spot where the
new
operator was used. That is your memory leak.valerie99 wrote:
Is this the proper delete?
No, because you are accessing
Groups[i]
afterGroups
has already been deleted.valerie99 wrote:
DiscountData->GroupID = Groups[i].GroupID;
I would have at least expected an access violation from this.
"Take only what you need and leave the land as you found it." - Native American Proverb
-
valerie99 wrote:
the app detected memory leak at this point:
Clicking on the line in the Debug window should take you to the spot where the
new
operator was used. That is your memory leak.valerie99 wrote:
Is this the proper delete?
No, because you are accessing
Groups[i]
afterGroups
has already been deleted.valerie99 wrote:
DiscountData->GroupID = Groups[i].GroupID;
I would have at least expected an access violation from this.
"Take only what you need and leave the land as you found it." - Native American Proverb
thanks. here is the memory leak report. when I clicked the first line it brings to "Groups = new GROUPSTRUCT[NumberofGroups];", I think it's becaue of "you are accessing Groups[i] after Groups has already been deleted", strangly no access violation. :\dev\c++\billing\voldisc\voldiscdlg.cpp(1702) : {839} normal block at 0x00FE58F0, 16 bytes long. Data: < > 01 00 00 00 CD CD CD CD 00 00 00 00 00 00 00 00 {465} normal block at 0x00FE5230, 1309 bytes long. Data:
48 65 61 64 65 72 20 4C 65 6E 67 74 68 3A 20 30 {460} normal block at 0x00FC28B8, 60 bytes long. Data: < a 0R > 04 EA 61 00 30 52 FE 00 1D 05 00 00 1D 05 00 00 {210} normal block at 0x00FBDB80, 14844 bytes long. Data: <5 a > 35 00 00 00 90 D2 61 00 98 81 13 00 00 00 00 00 {209} normal block at 0x00FBDB28, 20 bytes long. Data: 42 49 4C 4C 44 41 54 41 5C 56 54 41 58 30 32 2E {208} normal block at 0x00FBDAC0, 36 bytes long. Data: < a 5 ( > B8 CC 61 00 35 00 00 00 28 DB FB 00 98 81 13 00 Object dump complete. So the major leak is {210} normal block at 0x00FBDB80, 14844 bytes long. Data: <5 a > 35 00 00 00 90 D2 61 00 98 81 13 00 00 00 00 00 , which I couldn't get there by clicking on, so I placed this line _CrtSetBreakAlloc(210); to set a user break point, here is the call stack when the breakpoint taken effect. _heap_alloc_dbg(unsigned int 14844, int 1, const char * 0x00000000, int 0) line 338 _nh_malloc_dbg(unsigned int 14844, int 0, int 1, const char * 0x00000000, int 0) line 248 + 21 bytes _malloc_dbg(unsigned int 14844, int 1, const char * 0x00000000, int 0) line 165 + 27 bytes operator new(unsigned int 14844) line 325 + 15 bytes CB::Open(const char * 0x00e29f69, int 0) line 915 + 27 bytes CB::CB(const char * 0x00e29f69, int 0) line 883 CB_DBF::CB_DBF(const char * 0x00e29f69, int 0) line 269 + 45 bytes OpenDbfHelper(const char * 0x00e29f69) line 93 + 40 bytes OpenDbf(CB_DBF * * 0x0064acf0 class CB_DBF * VTax, const char * 0x00e29f69, int & 0, std::basic_string,std::allocator > * 0x00fafdcc {0x00000000 ""}) line 46 + 9 bytes CVoldiscDlg::OpenDBFs() line 838 + 27 bytes Run(void * 0x0012fd5c) line 2557 + 8 bytes _AfxThreadEntry(void * 0x0012f6cc) line 112 + 13 bytes _threadstartex(void * 0x00e24b90) line 212 + 13 bytes KERNEL32! 7c57b388() could u give me some help about how to nerrow down where the leak starts? thank you !
-
valerie99 wrote:
Is this the proper delete?
Yes, except you don't need to check if
Groups
is not null, before deleting. IfGroups
is null thendelete
simply does nothing. My question is: Are you realy trying to accessGroups
after deleting them.DiscountData->GroupID = Groups[i].GroupID;
INTP Every thing is relative...thanks for your reply. if I step into the program, it's actually working by this float: if ( Groups ) { delete[] Groups; Groups = NULL; } NumberofGroups = this->GetContributoryAmounts (mainPos); Groups = new GROUPSTRUCT[NumberofGroups]; for ( i = 0; i < NumberofGroups; i++ ) { Discount->GetGroup( Groups[i].GroupID ); Groups[i].TotalContributory = 0.0; } for ( i = 0; i < NumberofGroups; i++ ) { DiscountData->GroupID = Groups[i].GroupID; DiscountData->TotalContributory = Groups[i].TotalContributory;
-
thanks. here is the memory leak report. when I clicked the first line it brings to "Groups = new GROUPSTRUCT[NumberofGroups];", I think it's becaue of "you are accessing Groups[i] after Groups has already been deleted", strangly no access violation. :\dev\c++\billing\voldisc\voldiscdlg.cpp(1702) : {839} normal block at 0x00FE58F0, 16 bytes long. Data: < > 01 00 00 00 CD CD CD CD 00 00 00 00 00 00 00 00 {465} normal block at 0x00FE5230, 1309 bytes long. Data:
48 65 61 64 65 72 20 4C 65 6E 67 74 68 3A 20 30 {460} normal block at 0x00FC28B8, 60 bytes long. Data: < a 0R > 04 EA 61 00 30 52 FE 00 1D 05 00 00 1D 05 00 00 {210} normal block at 0x00FBDB80, 14844 bytes long. Data: <5 a > 35 00 00 00 90 D2 61 00 98 81 13 00 00 00 00 00 {209} normal block at 0x00FBDB28, 20 bytes long. Data: 42 49 4C 4C 44 41 54 41 5C 56 54 41 58 30 32 2E {208} normal block at 0x00FBDAC0, 36 bytes long. Data: < a 5 ( > B8 CC 61 00 35 00 00 00 28 DB FB 00 98 81 13 00 Object dump complete. So the major leak is {210} normal block at 0x00FBDB80, 14844 bytes long. Data: <5 a > 35 00 00 00 90 D2 61 00 98 81 13 00 00 00 00 00 , which I couldn't get there by clicking on, so I placed this line _CrtSetBreakAlloc(210); to set a user break point, here is the call stack when the breakpoint taken effect. _heap_alloc_dbg(unsigned int 14844, int 1, const char * 0x00000000, int 0) line 338 _nh_malloc_dbg(unsigned int 14844, int 0, int 1, const char * 0x00000000, int 0) line 248 + 21 bytes _malloc_dbg(unsigned int 14844, int 1, const char * 0x00000000, int 0) line 165 + 27 bytes operator new(unsigned int 14844) line 325 + 15 bytes CB::Open(const char * 0x00e29f69, int 0) line 915 + 27 bytes CB::CB(const char * 0x00e29f69, int 0) line 883 CB_DBF::CB_DBF(const char * 0x00e29f69, int 0) line 269 + 45 bytes OpenDbfHelper(const char * 0x00e29f69) line 93 + 40 bytes OpenDbf(CB_DBF * * 0x0064acf0 class CB_DBF * VTax, const char * 0x00e29f69, int & 0, std::basic_string,std::allocator > * 0x00fafdcc {0x00000000 ""}) line 46 + 9 bytes CVoldiscDlg::OpenDBFs() line 838 + 27 bytes Run(void * 0x0012fd5c) line 2557 + 8 bytes _AfxThreadEntry(void * 0x0012f6cc) line 112 + 13 bytes _threadstartex(void * 0x00e24b90) line 212 + 13 bytes KERNEL32! 7c57b388() could u give me some help about how to nerrow down where the leak starts? thank you !
valerie99 wrote:
strangly no access violation
Some times the exception is generated after it occurs, when you are in an etirely different place in your code. Thats why they are so hard to track down, where the exception is generated and where it actualy occured may be to totaly different places. If you fix what you can see for a fact is wrong, then the problem may go away. INTP Every thing is relative...
-
thanks. here is the memory leak report. when I clicked the first line it brings to "Groups = new GROUPSTRUCT[NumberofGroups];", I think it's becaue of "you are accessing Groups[i] after Groups has already been deleted", strangly no access violation. :\dev\c++\billing\voldisc\voldiscdlg.cpp(1702) : {839} normal block at 0x00FE58F0, 16 bytes long. Data: < > 01 00 00 00 CD CD CD CD 00 00 00 00 00 00 00 00 {465} normal block at 0x00FE5230, 1309 bytes long. Data:
48 65 61 64 65 72 20 4C 65 6E 67 74 68 3A 20 30 {460} normal block at 0x00FC28B8, 60 bytes long. Data: < a 0R > 04 EA 61 00 30 52 FE 00 1D 05 00 00 1D 05 00 00 {210} normal block at 0x00FBDB80, 14844 bytes long. Data: <5 a > 35 00 00 00 90 D2 61 00 98 81 13 00 00 00 00 00 {209} normal block at 0x00FBDB28, 20 bytes long. Data: 42 49 4C 4C 44 41 54 41 5C 56 54 41 58 30 32 2E {208} normal block at 0x00FBDAC0, 36 bytes long. Data: < a 5 ( > B8 CC 61 00 35 00 00 00 28 DB FB 00 98 81 13 00 Object dump complete. So the major leak is {210} normal block at 0x00FBDB80, 14844 bytes long. Data: <5 a > 35 00 00 00 90 D2 61 00 98 81 13 00 00 00 00 00 , which I couldn't get there by clicking on, so I placed this line _CrtSetBreakAlloc(210); to set a user break point, here is the call stack when the breakpoint taken effect. _heap_alloc_dbg(unsigned int 14844, int 1, const char * 0x00000000, int 0) line 338 _nh_malloc_dbg(unsigned int 14844, int 0, int 1, const char * 0x00000000, int 0) line 248 + 21 bytes _malloc_dbg(unsigned int 14844, int 1, const char * 0x00000000, int 0) line 165 + 27 bytes operator new(unsigned int 14844) line 325 + 15 bytes CB::Open(const char * 0x00e29f69, int 0) line 915 + 27 bytes CB::CB(const char * 0x00e29f69, int 0) line 883 CB_DBF::CB_DBF(const char * 0x00e29f69, int 0) line 269 + 45 bytes OpenDbfHelper(const char * 0x00e29f69) line 93 + 40 bytes OpenDbf(CB_DBF * * 0x0064acf0 class CB_DBF * VTax, const char * 0x00e29f69, int & 0, std::basic_string,std::allocator > * 0x00fafdcc {0x00000000 ""}) line 46 + 9 bytes CVoldiscDlg::OpenDBFs() line 838 + 27 bytes Run(void * 0x0012fd5c) line 2557 + 8 bytes _AfxThreadEntry(void * 0x0012f6cc) line 112 + 13 bytes _threadstartex(void * 0x00e24b90) line 212 + 13 bytes KERNEL32! 7c57b388() could u give me some help about how to nerrow down where the leak starts? thank you !
What does this code snippet produce for you. Some of the values I just guessed since I did not know how you were using them.
class GROUPSTRUCT
{
public:
int GroupID;
double TotalContributory;
};void main( void )
{
int NumberofGroups = 15;
GROUPSTRUCT *Groups = new GROUPSTRUCT[NumberofGroups];if (Groups != NULL) { for (int i = 0; i < NumberofGroups; i++) { //Discount->GetGroup( Groups\[i\].GroupID ); Groups\[i\].TotalContributory = 0.0; } delete \[\] Groups; Groups = NULL; }
}
Any leaks?
"Take only what you need and leave the land as you found it." - Native American Proverb
-
valerie99 wrote:
strangly no access violation
Some times the exception is generated after it occurs, when you are in an etirely different place in your code. Thats why they are so hard to track down, where the exception is generated and where it actualy occured may be to totaly different places. If you fix what you can see for a fact is wrong, then the problem may go away. INTP Every thing is relative...
because the "NumberofGroups = this->GetContributoryAmounts (mainPos); " will call the "Groups = new GROUPSTRUCT[NumberofGroups]; ", so it's actually not trying to access right after deleting, here is the flow: if ( Groups ) { delete[] Groups; Groups = NULL; } NumberofGroups = this->GetContributoryAmounts (mainPos); Groups = new GROUPSTRUCT[NumberofGroups]; for ( i = 0; i < NumberofGroups; i++ ) { Discount->GetGroup( Groups[i].GroupID ); Groups[i].TotalContributory = 0.0; } for ( i = 0; i < NumberofGroups; i++ ) { DiscountData->GroupID = Groups[i].GroupID; DiscountData->TotalContributory = Groups[i].TotalContributory;
-
because the "NumberofGroups = this->GetContributoryAmounts (mainPos); " will call the "Groups = new GROUPSTRUCT[NumberofGroups]; ", so it's actually not trying to access right after deleting, here is the flow: if ( Groups ) { delete[] Groups; Groups = NULL; } NumberofGroups = this->GetContributoryAmounts (mainPos); Groups = new GROUPSTRUCT[NumberofGroups]; for ( i = 0; i < NumberofGroups; i++ ) { Discount->GetGroup( Groups[i].GroupID ); Groups[i].TotalContributory = 0.0; } for ( i = 0; i < NumberofGroups; i++ ) { DiscountData->GroupID = Groups[i].GroupID; DiscountData->TotalContributory = Groups[i].TotalContributory;
valerie99 wrote:
NumberofGroups = this->GetContributoryAmounts (mainPos);
Since you indicate that this will eventually call the
new
operator, where is the correspondingdelete
?
"Take only what you need and leave the land as you found it." - Native American Proverb
-
because the "NumberofGroups = this->GetContributoryAmounts (mainPos); " will call the "Groups = new GROUPSTRUCT[NumberofGroups]; ", so it's actually not trying to access right after deleting, here is the flow: if ( Groups ) { delete[] Groups; Groups = NULL; } NumberofGroups = this->GetContributoryAmounts (mainPos); Groups = new GROUPSTRUCT[NumberofGroups]; for ( i = 0; i < NumberofGroups; i++ ) { Discount->GetGroup( Groups[i].GroupID ); Groups[i].TotalContributory = 0.0; } for ( i = 0; i < NumberofGroups; i++ ) { DiscountData->GroupID = Groups[i].GroupID; DiscountData->TotalContributory = Groups[i].TotalContributory;
According to what you said:
valerie99 wrote:
because the "NumberofGroups = this->GetContributoryAmounts (mainPos); " will call the "Groups = new GROUPSTRUCT[NumberofGroups];
so, if this is true, when you do this:
valerie99 wrote:
NumberofGroups = this->GetContributoryAmounts (mainPos); Groups = new GROUPSTRUCT[NumberofGroups];
the first line allocates memory with new and assigns the pointer to Groups, but then you also do your own new and assign it to Groups. Therefore the previous assignment from NumberofGroups = this->GetContributoryAmounts (mainPos); is lost, and a memory leak. Hope that helps. Karl - WK5M PP-ASEL-IA (N43CS) PGP Key: 0xDB02E193 PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193