|
Actually it did address your problem for the information you gave. If it was new information, I have no idea.
You were trying to free an invalid pointer (probably NULL), so how was it not “problem oriented”?
The new code you posted suffers from some of the problems I told you about, but if you do not call your personal free function twice it will be no problem. Otherwise you will get the same errors you originally posted about.
I know C inside and out – if you do not understand the answer, then I can not help you.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
Look I am watching my code, and I do not try to free NULL pointers.
then again if you see something in my code that is not O.K please post a code snippet that shows the problem so I can understand exectly where i am falling.
I posted a simple example in a main func.
may threw looking at that you can explain exactly what's wrong.
I appreciate what ever help you can give me.
|
|
|
|
|
The original code snippet I posted shows everything you need to know about freeing that type of array. What the rest of your code is doing, I have no clue.
The only thing wrong with your second post of code was that it did not check if any of the pointers where NULL before freeing them, nor did you set them to NULL after freeing them. Of course that was basically the problem with you first post of code.
I have not seen, nor want to, the rest of your code, but you should also make sure that any slot (colName[0] is a slot) is empty (points to NULL) before assigning a new pointer to it, or you will again have memory leaks.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
Ok, you've allocated the necessary memory for the struct and its members. But when you try to access the pointers to free the memory they point to, you get an access violation. That tells me that maybe you're losing track of the pointers somewhere along the way.
I'd suggest putting in asserts in your code to make sure the pointers aren't null. Something like:
assert(t != NULL);
assert(t->local_data != NULL);
assert(t->locat_data->colName != NULL);
for(i = 0 ; i < width ; i++)
{
assert(t->local_data->colName[i] != NULL);
free(t->local_data->colName[i]);
}
free(t->local_data_colName);
Backtrack from this location to the one in which you originally allocated memory. Liberally place asserts along the way to make sure that the pointers don't get lost. Hopefully this till catch where the problem is originating.
|
|
|
|
|
That is actually a good idea, but look at your assert. It is a good idea but if it hits, then it just shows that an ‘if’ statement should be there. So if the assert complains, then something is wrong because the same function was called twice without t->local_data_colName being deleted (or set to an invalid value – most likely).
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
#include <stdio.h>
#include <string.h>
#include <malloc.h>
void main ()
{
int num = 2;
char** str_array;
char str1[] = "first string";
char str2[] = "second string";
str_array = (char**)malloc(sizeof(char*)*num);
str_array[0] = (char*)malloc(sizeof(char)*strlen(str1));
str_array[1] = (char*)malloc(sizeof(char)*strlen(str2));
strcpy (str_array[0],str1);
strcpy (str_array[1],str2);
printf("%s \n",str_array[0]);
printf("%s \n",str_array[1]);
free(str_array[0]);
free(str_array[1]);
free(str_array);
}
Please help me spot the mistake.
|
|
|
|
|
LOL – That would actually work. It makes no since, but it would work.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
gizmokaka wrote:
str_array[0] = (char*)malloc(sizeof(char)*strlen(str1));
str_array[1] = (char*)malloc(sizeof(char)*strlen(str2));
strcpy (str_array[0],str1);
strcpy (str_array[1],str2);
You aren't allocating memory for the terminating /0 in the strings, which causes strcpy() to overwrite memory outside the allocated block. Depending on the implementation, that may trash the metadata used by malloc() /free() and cause an error.
|
|
|
|
|
Markkuk
Thanks man it's just what I was looking for.
I probably will address you with further questions later on,
good day.
|
|
|
|
|
lol - I missed that
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
|
Element = void*
I'm experiencing the same problem in a somewhat different situation
Here is the relevant code:
Element string_to_element(const char* val)
{
Element localElem = malloc(sizeof(val));
strcpy((char*)localElem , val);
return localElem;
}
const char* element_to_string(Element e)
{
int i;
const char* localStr = (char*)malloc(sizeof(char)*(strlen((char*)e)+1));
for (i = strlen(localStr) ; i > 0 ;i--)
((char*)e)[i] = NULL;
strcpy(localStr , (char*)e);
return localStr;
}
void string_free_func(Element strElem)
{
char* string;
if(strElem == NULL)
return;
string = (char*)strElem;
free(string);
}
void main()
{
char* str2;
char* str1 = "simple string";
Element e1 , e2;
e1 = string_to_element(str1);
str2 = element_to_string(e1);
string_free_func(e1);
}
This code is a bit modified but should illustrate the problem I'm facing.
any help would be most appreciate
|
|
|
|
|
Be care with pointers!
void main ()
{
int num = 2<code>, i</code>;
char** str_array;
char str1[] = "first string";
char str2[] = "second string";
<code>str_array=NULL;</code>
str_array = (char**)malloc(sizeof(char*)*num);
<code>for(i=0;i<num,i++) str_array[i]=NULL;</code>
str_array[0] = (char*)malloc(sizeof(char)*strlen(str1));
<code>for(i=0;i<strlen(str1),i++) str_array[0][i]=NULL;</code>
str_array[1] = (char*)malloc(sizeof(char)*strlen(str2));
<code>for(i=0;i<strlen(str2),i++) str_array[1][i]=NULL;</code>
strcpy (str_array[0],str1);
strcpy (str_array[1],str2);
printf("%s \n",str_array[0]);
printf("%s \n",str_array[1]);
<code>if(str_array[0]!=NULL)</code>
free(str_array[0]);
<code>if(str_array[1]!=NULL)</code>
free(str_array[1]);
<code>if(str_array!=NULL)</code>
free(str_array);
}
Russell
|
|
|
|
|
What is the best way in MFC to programmatically close a CView derived class instance?
I'm currently posting a WM_CLOSE to the views parent frame window. Is this the common way to do this?
|
|
|
|
|
Yes.
then the frame calls DestroyWindow to destroy itself. The message will be sended to all the childs, so also to your CView derived class.
Then you have only to write the right code to destroy correctly the view.
Russell
|
|
|
|
|
Thanks.
I was having a problem elsewhere in the code and I was trying to detemine if this method was sound or if it might mess up the MFC internal houskeeping somehow.
Most of the books I have don't cover this except one which suggested this technique.
Again, thanks for your help.
|
|
|
|
|
In addition to Russell's reply -
Typically you'd use DestroyWindow() to destroy a window but with MFC doc/view, that
would bypass the prompt to save an unsaved document and delete the document if its
autodelete flag is set.
I disagree with Russell's statement that the WM_CLOSE will be sent to the children, but
it's generally not an issue anyway since only frame windows do something useful with the
message.
I always figured the reason it's not documented is MFC just assumes only the user will
close a window. Just one of the many irritating things about the doc/view architecture.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: Typically you'd use DestroyWindow() to destroy a window but with MFC doc/view
I hear you. I'm definitely not out to bypass MFC on the close. Actually, that was my concern. I was afraid I might be bypassing something important in MFC closing the view by sending the message to the frame. I was getting funky behavior with my window list when I tried something that might be considered unorthodox elsewhere so I figured I might be messing the whole MFC internal management scheme up.
Sometimes cause and effect is about all I have to go off of when the MFC source calls the win32 api internally so I figure I'll ask the pros here about what they might know about the internal behavior in general.
Thanks for the response.
|
|
|
|
|
bob16972 wrote: Sometimes cause and effect is about all I have to go off of when the MFC source calls the win32 api internally
Yeah That's why the best documentation IMO is the MFC source code.
Cheers!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
It depends a lot on which properties had to have.
In my project, I had a CScrollView as MainView and then the possibility to hold a CFormView for EVERY element on the screen (up to 48). All secondary views should close without problems and /or asking to save changes on the document. I managed it with:
BOOL CMyDoc::CanCloseFrame(CFrameWnd* pFrame)
{ int nError = 0;
CView* pFrmView = pFrame->GetActiveView ();
if (pFrmView->IsKindOf (RUNTIME_CLASS (CFormView)))
return TRUE;
POSITION pos = GetFirstViewPosition ();
while (pos)
{ CView* pView = GetNextView (pos);
if (pView->IsKindOf (RUNTIME_CLASS (CFormView)))
{ CFrameWnd* pTempFrame = pView->GetParentFrame ();
if (pTempFrame)
pTempFrame->DestroyWindow ();
}
}
return CDocument::CanCloseFrame(pFrame);
}
Then I only have coded the OnDestroy in every secondary window to release all used memory and delete contents of listboxes, array and so on.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|
|
anyone know of a good hierarchical tree drawing utility/library (MFC or even JS/DHTML) that can display trees of arbitrary depth, with arbitrary number of children per node ? this is for drawing the results of an expression parser, where parent nodes are functions and the leaves are parameters. the trees are non-recursive, ordered; nodes have single-parents and unlimited children (which can be other nodes or leaves).
i do not want to use a CTreeCtrl-style tree. i want something more like this (sample 1a) - a proper graph.
|
|
|
|
|
Chris Losinger wrote: i want something more like this (sample 1a) - a proper graph.
I have never attempted it for that purpose, but GraphViz does those type outputs:
http://www.graphviz.org/Documentation.php[^]
http://www.graphviz.org/Gallery/directed/unix.html[^]
I have never used it as a library, but I do use it as a utility (build graph language -- execute graphviz -- read image), Doxygen does the same thing, including hyperlinked text within the images (I have not gone that far, though debated on digging into their code to try).
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
GraphViz dot for your example:
digraph G {
S -> NP -> el;
S -> VP -> V1 -> hizo;
VP -> V2 -> decir;
VP ->NP1 -> lo;
VP -> NP2 -> ami
}
of course without the renaming of V1,V2 and NP1 NP2 to V and NP, but I could do that later.
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
I have an MDI application with two view types for the same document. I am creating the instances of the second view type from an instance of the first view and then hiding all instances of the first view type using CFrameWnd::ActivateFrame() with a parameter equal to SW_HIDE. When all instances of the second view type are closed, all instances of the first view are reenabled using CFrameWnd::ActivateFrame() with a parameter equal to SW_SHOW.
It appears to work under certain circumstances and the window list in the menu appears to hide the references to those hidden frames. However, as I start to post WM_CLOSE messages to the visible views frame window class the window list gets quite out of sync and at the point I try to renable the instances of the first view types, nothing shows up in the window list even though the windows themselves are visible in the client area.
If I don't hide any views the window list remains in sync but I'd rather hide the views if possible.
Has anybody tried something like this before and got it to work?
// Here are some snippets
// CTheApp::InitInstance()
// First template
m_pDocTemplateFirst = new CMultiDocTemplate(
IDR_FIRST_TYPE,
RUNTIME_CLASS(CTheDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CFirstView));
if (!m_pDocTemplateFirst)
return FALSE;
AddDocTemplate(m_pDocTemplateFirst);
// Second template
m_pDocTemplateSecond = new CMultiDocTemplate(
IDR_SECOND_TYPE,
RUNTIME_CLASS(CTheDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CSecondView));
if (!m_pDocTemplateSecond)
return FALSE;
AddDocTemplate(m_pDocTemplateSecond);
// From the document class
// Creating the new view based on the second doctemplate
CFrameWnd* pFrame=pDocTemplate->CreateNewFrame(this,NULL);
if (pFrame) {
pDocTemplate->InitialUpdateFrame(pFrame,this,TRUE);
}
// Elsewhere
// Closing the frame and subsequently the view
pFrame->PostMessage(WM_CLOSE);
|
|
|
|
|
For some reason, this seems to fix the refresh issue.
In my CTheDoc::CanCloseFrame(), I have to do this to a child frame when closing it if I have other frames that are deactivated that are also associated with the document.
BOOL CTheDoc::CanCloseFrame(CFrameWnd* pFrame)
{
pFrame->ActivateFrame(SW_HIDE);
return CTheDoc::CanCloseFrame(pFrame);
}
Any ideas on why this would be necessary? Or am I just getting a false positive?
|
|
|
|