|
Hamed Mosavi wrote: void SetPath(CString strPath)
{
memset(m_pA->pSzPath, NULL, MAX_PATH);
int len = min(MAX_PATH, strPath.GetLength());
strncpy(m_pA->pSzPath, strPath, len); // Path to folder
m_pA->bPathUpdated = TRUE; // a volatile BOOL
}
There still may be a problem with the string termination, possibly causing memory corruption or overrun.
Assuming the size of the pSzPath is MAX_PATH, maybe try:
void SetPath(CString strPath)
{
memset(m_pA->pSzPath, 0, MAX_PATH);
int len = min(MAX_PATH<font color="Red"> - 1</font>, strPath.GetLength());
strncpy(m_pA->pSzPath, strPath, len);
<font color="Red"><font><font> m_pA->pSzPath</font></font>[len] = 0;</font>
<font> m_pA->bPathUpdated = TRUE;
}</font> You shouldn't need the empty call unless you want to explicitly empty the string.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: (MAX_PATH - 1,
That's right. I took a closer look at my code and I saw that -1 in mine. Sorry to forget to add it here.
Why do I need to call this:
m_pA->pSzPath[len] = 0;
when I just called this:
memset(m_pA->pSzPath, 0, MAX_PATH);
len will be MAX_PATH-1 or something smaller, so that this char* always has the \0 in the end, before being filled with strncpy . This \0 is not the problem here. I think I might need to find some free time and check the resulting assembly code, perhaps I find something there.
Mark Salsbery wrote: You shouldn't need the empty call
That's what bothers me here. There's obviously something's wrong
Anyway thank you so much for your kind help. I appreciate it.
Thanks Mark.
// "Life is very short and is very fragile also." Yanni while (I'm_alive) { cout<<"I love programming."; }
|
|
|
|
|
You're right - never mind about the NULL termination then
How are you detecting the memory leak?
The CString destructor should free the contents of the string. If this isn't happening
then the destructor isn't getting called.
Is your thread shutdown all the way before the app exits?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: the destructor isn't getting called.
Is your thread shutdown all the way before the app exits?
Nope! Both destructor and thread work just fine! After I finish the job, I'll be back to find the reason even if I have to use a disassembler and read assembly code, because it tried me crazy and got a lot of my time, and of course yours.
At the moment, if you are interested, I took a snapshot of the thread and the debug window and uploaded them here:
I removed all codes from the thread to make it simpler. even this code has the memory leak.
http://www.sarvsoft.com/CrazyMemLeak/1.jpg
http://www.sarvsoft.com/CrazyMemLeak/2.jpg
If you are interested in GUIs, here's an image of the GUI but in my own language. Inspired by Vista. I'm currently implementing that left most innocence(!) thumb list:
http://www.sarvsoft.com/CrazyMemLeak/3.jpg
// "Life is very short and is very fragile also." Yanni while (I'm_alive) { cout<<"I love programming."; }
|
|
|
|
|
My application was generared with wizard. It'is SDI.
The problem:
The document do not automatically attach to the view.
The document is creating but the m_pDocument in the view class is always NULL.
How can I solve this problem?
-- modified at 2:03 Saturday 8th September, 2007
|
|
|
|
|
thats vary simple.
say for example,
your sdi application is named as example,
then your view will be CexampleView
and your document class will be CexampleDoc.
now your requirement is to get the object of CexampleDoc in CexampleView right?,
if it is so,
the following is the logic.
in CexampleView class(.h file) define a variable like this.
CexampleDoc *pDoc;
and in constructor or ondraw,
pDoc=GetDocument();
now you can access the document class with pDoc.
|
|
|
|
|
Thanks but I know document/view architecture. I found the problem.
IMPLEMENT_DYNCREATE(CSalesmanView, CScrollView)
BEGIN_MESSAGE_MAP(CSalesmanView, CScrollView)
changed to
IMPLEMENT_DYNCREATE(CSalesmanView, CFormView)
BEGIN_MESSAGE_MAP(CSalesmanView, CFormView)
I was changed the parent of CSalesmanView from CScrollView to CFormView by hand and forgot to change this.
SOLVED
|
|
|
|
|
I am working on a treeview (straight win32) and was wondering if anyone knew how I could change the text apperance? (Yes, I know how to change text color in general). I can not seem to find an obvious way to do this. I have tried using TreeView_SetTextColor but that will change the text color for all of tree. I only want to change one branch of my tree.
http://rafb.net/p/7VhWKn68.html (tree.h) and http://rafb.net/p/6ltyVn44.html (tree.cpp)
|
|
|
|
|
Handle NM_CUSTOMDRAW , you can change the text and background colors for each item.
|
|
|
|
|
I have looked up using NM_CUSTOMDRAW but I am not sure how I would use it with my code. How would I use it in relation to my code?
|
|
|
|
|
See this article[^], it's about list views but the procedure is similar for tree views.
|
|
|
|
|
Good article, however, I noticed they used there list as a class but I do not.
Also, could I use this function to change the font size?
|
|
|
|
|
Hello all,
I'm having a problem when trying to free a string that is pointed from a member of colName array.
That is of course after I'm allocation memory for the colName array, and each of it's members.
the struct i'm working on:
typedef struct
{
char** colName;
const struct element_interface** ifc;
Element* temp_row;
}data;
typedef struct table_rec
{
char TabInitFlag;
int iterator;
data* localData;
char** last_found_array;
Matrix tableArray;
int tableWidth;
int last_found;
}table_rec;
The command that I'm using to free the string.
int num;
for(i = 0; i < num; i++)
{
free(colNum[i]);
}
The error I'm receiving in the first iteration (as any):
Unhandled exception at 0x00418780 in project.exe: 0xC0000005: Access violation reading location 0xfdfdfe01.
Thank you,
Gizmokaka
|
|
|
|
|
gizmokaka wrote: That is of course after I'm allocation memory for the colName array, and each of it's members.
Just to confirm, you are allocating memory for the pointer that points to an array of pointers, correct? Something like:
char **myArray = malloc(sizeof(char *) * 10);
int i;
for(i = 0; i < 10; i++)
{
myArray[i] = malloc(sizeof(char) * 15);
}
|
|
|
|
|
yes that is just about how I allocated the space.
|
|
|
|
|
Wow! I am glad that was not a physical blow. (Just messing with you )
First the ‘data’ structure needs values that tells us how many items are in each array contained in the structure, otherwise we will not know how many to free.
The “data” structure contains an array of names (colName), when freeing the names you need to ensure that the pointer to the array and that each pointer to a name is valid or you will get an error (if you are lucky) or unexpected results.
To free the array do the following:
1) Check that ‘colName’ is not NULL; write an initialization function to ensure that it is NULL when it is created, similar to a C++ constructor method. You could just write “data mydata = {0}” when declaring a ‘data’ type and all members will be set to zero (NULL).
2) Before calling ‘free’ for an individual item, make sure that it is not pointing to NULL, before freeing it.
3) After calling ‘free’, set the item (colName[i]) to NULL, so you will not try to free it a second time (by accident).
4) After freeing the individual items, you need to free ‘colName’ and set it to NULL, because it not longer points to any valid data.
Example:
if( data.colName )
{
int i;
for( i=0; i < data.NameCount; ++i )
{
if( data.colName[i] )
{
free(data.colName[i]);
data.colName[i] = NULL;
}
}
free(data.colName);
data.colName = NULL;
}
If you understand all of that, then welcome to the world of real programmers!
P.S. I am ignoring the fact that your example is freeing something called colNum, which does not exist.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
Hello john and thanks for the attention, never the less, you did not supply me with any new information, for things I didn't do , nor was your answer "problem oriented" because it didn't address my problem.
my problem is specific, I am declaring a char** pointer inside my struct that 's purpose is to hold an array of chars in the near future.
during run time I am initializing it with values(pointers to strings).
now in one of my functions I am supposed to free the memory each of the members take, and then the pointer itself.
for(i = 0 ; i < width ; i++)
{
free(t->local_data->colName[i]);
}
free(t->local_data_colName);
still for some odd reason I get the error already posted.
|
|
|
|
|
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.
|
|
|
|