Click to See Complete Forum and Search --> : wrap c API
peterwang
October 31st, 2002, 11:14 PM
Hi all,
I want to create a class to warp the MySQL C API, the problem is when I try to let a MYSQL mySql become a data member of the new class, I found I can't assign the mySql using this normal way mysql= sql, because MYSQL is a C structure, nobody overload the operator=, and MYSQL do have some pointer data members, so, what's the better way to handle it, wrap MYSQL first?
Thanks.
peter
zdf
November 1st, 2002, 04:23 AM
Hi Peter!
Please, post the relevant code and the error messages.
As far as I know the code below must be ok on all c++ compilers.
int main()
{
struct S
{
int i;
const char* pc;
}
s1 = { 12, "abc" }, s2 = { 34, "def" };
s2 = s1;
return 0;
}
Regards,
Andreas Masur
November 1st, 2002, 07:29 AM
Originally posted by zdf
As far as I know the code below must be ok on all c++ compilers.
int main()
{
struct S
{
int i;
const char* pc;
}
s1 = { 12, "abc" }, s2 = { 34, "def" };
s2 = s1;
return 0;
}
Regards,
Well the code is okay but contains a potential danger which you should point out. At the line where you assigning 's1' to 's2' the default copy constructor will be called. The default copy constructor just copies member to member. So after the assignment 's2' will have '34' and the pointer will point to 'def'. Since these string are const literals it does not matter here. But if you would have allocated the memory for these strings dynamically (on the heap) the above code would cause a memory leak.
If you have a structure/class with dynamic memory a deep copy is required to guarantee that all members gets copied properly. To make a deep copy, you must write a copy constructor and overload the assignment operator.
class CFoo()
{
public:
// Constructor
CFoo() { m_pArray = new char[100]; }
// Destructor
~CFoo() { delete [] m_pArray; }
// Copy constructor
CFoo(const CFoo &refcSource)
{
// Allocate new space
m_pArray = new char[strlen(refcSource.m_pArray) + 1];
// Copy values
strcpy(m_pArray, refcSource.m_pArray);
}
// Assignment operator
CFoo& CFoo :: operator=(const CFoo &refcSource)
{
// Check whether it is the same instance
if(refcSource != this)
{
// Release old memory
delete [] m_pArray;
// Allocate new space
m_pArray = new char[strlen(refcSource.m_pArray) + 1];
// Copy values
strcpy(m_pArray, refcSource.m_pArray);
}
return *this;
}
private:
char *m_pArray;
};
Edited: Added some spaces between '::' and 'operator' to avoid the conversion into a smilie...
peterwang
November 1st, 2002, 08:19 AM
MYSQL is a C-style structure, it has a few pointers data member inside, this is the point.
Andreas Masur
November 1st, 2002, 08:48 AM
Originally posted by peterwang
MYSQL is a C-style structure, it has a few pointers data member inside, this is the point.
Than you have to do a deep copy as shown in my previous post...
AnthonyMai
November 1st, 2002, 10:17 AM
int main()
{
struct S
{
int i;
const char* pc;
}
s1 = { 12, "abc" }, s2 = { 34, "def" };
s2 = s1;
return 0;
}
Since these string are const literals it does not matter here. But if you would have allocated the memory for these strings dynamically (on the heap) the above code would cause a memory leak.
I find the above comment extremely incredible!!!
[Yves : next time say : "I don't agree with this comment"]
A const char pointer means it is pointing to something that users of that pointer can NOT manipulate that memory, but can only read. "Manipulation" includes memory allocation and memory free.
If p is a const char pointer, you can NOT do a "delete [] p;" The compiler wouldn't allow you.
Having a const char pointer means you could not used that pointer when freeing the memory. So you should not initialze that pointer from a memory allocation, either. If the const char pointer points to memory dynamically allocated, it means there is some other, none const, char pointer, that is responsible for memory allocation and free, and you just cast the none const pointer to a const pointer to use it.
Since your const char pointer is not responsible for memory allocation and free, it can NOT be held responsible for any memory leak should it happen.
Here is an example code how const char pointer works:
char* pString = NULL;
const char* pConstString = NULL;
//...
pString = new char[256];
// You have to allocate using a none const pointer.
strcpy(pString, "Hello world");
// You have to fill in meaningful information using none const ptr
pConstString = (const char*)pString;
//You can now use pConstString while avoiding modifying it.
//..
//Use pConstString
//..
strcat(pString, "!");
// To modify the string you still need to use the original
//none const char pointer.
//..
pConstString = NULL; // Done with using it.
//delete [] pConstString;
// This would not work!!!
delete [] pString;
// You have to delete using the original none-const char ptr.
You see, pConstString was never responsible for new and delete, instead, pString was. So if there is a memory leak, pConstString is not responsible. Instead pString is responsible.
peterwang
November 1st, 2002, 11:05 AM
Originally posted by Andreas Masur
Than you have to do a deep copy as shown in my previous post...
I can't modify the mysql.h which defined the MYSQL, the MYSQL does't have any constructor, because it's a C-Style structure, any c source code can use it.
Andreas Masur
November 1st, 2002, 11:31 AM
Originally posted by AnthonyMai
I find the above comment extremely incredible!!!
[Yves : next time say : "I don't agree with this comment"]
<snipped the rest>
Ok...if you would read the original post where I was replying to then you would see that he was showing an example about a struct and its assignment operator.
And even the OP is talking about a class. If you have a class which contains dynamic allocated memory then you have to provide both copy and assignment constructor. That is what I was showing with my sample code. Nothing more, nothing less.
Your example might be nice but it has nothing to do with anything I said since it is some kind of C-stylish 'strcpy()' etc. and therefore worthless for this discussion...
Andreas Masur
November 1st, 2002, 11:32 AM
Originally posted by peterwang
I can't modify the mysql.h which defined the MYSQL, the MYSQL does't have any constructor, because it's a C-Style structure, any c source code can use it.
Well...than you could wrap this structure with a custom-made class on your own...
usman999_1
November 1st, 2002, 12:47 PM
Andreas u can disable similies in ur post by just checking the checkbox with an option Disable Smilies in This Post ;)
Regards,
Usman.
AnthonyMai
November 1st, 2002, 02:40 PM
Ok...if you would read the original post where I was replying to then you would see that he was showing an example about a struct and its assignment operator.
And even the OP is talking about a class. If you have a class which contains dynamic allocated memory then you have to provide both copy and assignment constructor. That is what I was showing with my sample code. Nothing more, nothing less.
Your example might be nice but it has nothing to do with anything I said since it is some kind of C-stylish 'strcpy()' etc. and therefore worthless for this discussion...
The point I made is that const char pointer never directly associate with dynamically allocated memory. So it can not be held responsible for not freeing memory and cause memory leak. This point is valid whether we are talking about C code or C++, and whether the const char pointer is a standard along point, or is a member of a struct or class, and it doesn't matter whether the const pointer is a global variable or a local variable. All it matter is if it is const, it has nothing to do with memory allocation and freeing.
[Yves : this is completly off-topic, even though it is worth knowing. Limit your off-topic discussions, or I'll just split them off the thread]
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.