|
-
August 3rd, 2006, 06:04 AM
#1
Porting from VC6 to Linux Fedora core 5 problem
Hi, I'm a new member in the forum. I have quite a problem here. Actually, I've posted it in www.cprogramming.com, but since I needed it to be resolved fast, I post it here also.
Recently, I ported my codes from Visual C 6 to Linux. But, what I meant about porting was only copy-pasted the entire code to a new KDevelop C/C++ project (also a little letter-case correction in the #include line ). The code was successfully compiled and built. But when I run it, there's a memory corruption error. I don' tknow what's wrong with it because it never happened before in VC6. The error was in the "myVector.push_back(mObject) ". And the myVector declaration was "vector<*MyObject> myVector". The strange thing was not all of the push_back methods was faulty. Only a few of them. And it gets more strange because when I moved the faulty method to the beginning of the function, it worked fine until the next push_back method. Here's the error message:
*** glibc detected *** ./mattinggame: malloc(): memory corruption:
0x09f67f70 ***
*
======= Backtrace: =========
/lib/libc.so.6[0xb49660]
/lib/libc.so.6(malloc+0x74)[0xb4ac7c]
/usr/lib/libstdc++.so.6(_Znwj+0x27)[0x220e4d7]
/usr/lib/libstdc++.so.6(_Znaj+0x1d)[0x220e60d]
./mattinggame[0x8056536]
./mattinggame[0x80567bb]
./mattinggame[0x80578c5]
./mattinggame[0x8057cb2]
./mattinggame[0x8057dd8]
./mattinggame[0x8052b49]
./mattinggame[0x807364c]
./mattinggame[0x807a5ff]
./mattinggame(__gxx_personality_v0+0x1de)[0x80499c2]
/lib/libc.so.6(__libc_start_main+0xdc)[0xafa7e4]
./mattinggame(__gxx_personality_v0+0x9d)[0x8049881]
======= Memory map: ========
001bb000-001be000 r-xp 00000000 fd:00 92170 /usr/lib/libXrandr.so.2.0.0
001be000-001bf000 rwxp 00002000 fd:00 92170 /usr/lib/libXrandr.so.2.0.0
001dd000-001e8000 r-xp 00000000 fd:00 3457623
/lib/libgcc_s-4.1.0-20060304.so.1
001e8000-001e9000 rwxp 0000a000 fd:00 3457623
/lib/libgcc_s-4.1.0-20060304.so.1
00215000-00216000 r-xp 00215000 00:00 0 [vdso]
00258000-00271000 r-xp 00000000 fd:00 3457612 /lib/ld-2.4.so
00271000-00272000 r-xp 00018000 fd:00 3457612 /lib/ld-2.4.so
00272000-00273000 rwxp 00019000 fd:00 3457612 /lib/ld-2.4.so
00548000-00592000 r-xp 00000000 fd:00 75310
/usr/local/lib/libSDL_mixer-1.2.so.0.2.5
00592000-0059c000 rwxp 0004a000 fd:00 75310
/usr/local/lib/libSDL_mixer-1.2.so.0.2.5
0059c000-005c0000 rwxp 0059c000 00:00 0
00680000-006e3000 r-xp 00000000 fd:00 71301
/usr/local/lib/libSDL-1.2.so.0.11.0
006e3000-006e5000 rwxp 00063000 fd:00 71301
/usr/local/lib/libSDL-1.2.so.0.11.0
006e5000-00700000 rwxp 006e5000 00:00 0
00ae5000-00c11000 r-xp 00000000 fd:00 3457618 /lib/libc-2.4.so
00c11000-00c14000 r-xp 0012b000 fd:00 3457618 /lib/libc-2.4.so
00c14000-00c15000 rwxp 0012e000 fd:00 3457618 /lib/libc-2.4.so
00c15000-00c18000 rwxp 00c15000 00:00 0
00c1a000-00c3d000 r-xp 00000000 fd:00 3457619 /lib/libm-2.4.so
00c3d000-00c3e000 r-xp 00022000 fd:00 3457619 /lib/libm-2.4.so
00c3e000-00c3f000 rwxp 00023000 fd:00 3457619 /lib/libm-2.4.so
00c41000-00c43000 r-xp 00000000 fd:00 3457620 /lib/libdl-2.4.so
00c43000-00c44000 r-xp 00001000 fd:00 3457620 /lib/libdl-2.4.so
00c44000-00c45000 rwxp 00002000 fd:00 3457620 /lib/libdl-2.4.so
00c47000-00d40000 r-xp 00000000 fd:00 92167 /usr/lib/libX11.so.6.2.0
00d40000-00d44000 rwxp 000f9000 fd:00 92167 /usr/lib/libX11.so.6.2.0
00d46000-00d48000 r-xp 00000000 fd:00 92165 /usr/lib/libXau.so.6.0.0
00d48000-00d49000 rwxp 00001000 fd:00 92165 /usr/lib/libXau.so.6.0.0
00d60000-00d65000 r-xp 00000000 fd:00 92166 /usr/lib/libXdmcp.so.6.0.0
00d65000-00d66000 rwxp 00004000 fd:00 92166 /usr/lib/libXdmcp.so.6.0.0
00d68000-00d77000 r-xp 00000000 fd:00 92169 /usr/lib/libXext.so.6.4.0
00d77000-00d78000 rwxp 0000e000 fd:00 92169 /usr/lib/libXext.so.6.4.0
00dc7000-00dcf000 r-xp 00000000 fd:00 92168 /usr/lib/libXrender.so.1.3.0
00dcf000-00dd0000 rwxp 00007000 fd:00 92168 /usr/lib/libXrender.so.1.3.0
00dd2000-00de2000 r-xp 00000000 fd:00 3457622 /lib/libpthread-2.4.so
00de2000-00de3000 r-xp 0000f000 fd:00 3457622 /lib/libpthread-2.4.so
00de3000-00de4000 rwxp 00010000 fd:00 3457622 /lib/libpthread-2.4.so
00de4000-00de6000 rwxp 00de4000 00:00 0
00de8000-00df1000 r-xp 00000000 fd:00 92172 /usr/lib/libXcursor.so.1.0.2
00df1000-00df2000 rwxp 00008000 fd:00 92172 /usr/lib/libXcursor.so.1.0.2
00df4000-00df8000 r-xp 00000000 fd:00 92171 /usr/lib/libXfixes.so.3.0.0
00df8000-00df9000 rwxp 00003000 fd:00 92171 /usr/lib/libXfixes.so.3.0.0
02157000-02239000 r-xp 00000000 fd:00 92179 /usr/lib/libstdc++.so.6.0.8
02239000-0223d000 r-xp 000e2000 fd:00 92179 /usr/lib/libstdc++.so.6.0.8
0223d000-0223e000 rwxp 000e6000 fd:00 92179 /usr/lib/libstdc++.so.6.0.8
0223e000-02244000 rwxp 0223e000 00:00 0
08048000-08087000 r-xp 00000000 fd:00 1533373
/home/benang/mattinggame/debug/src/mattinggame
08087000-08088000 rw-p 0003e000 fd:00 1533373
/home/benang/mattinggame/debug/src/mattinggame
098e0000-09d85000 rw-p 098e0000 00:00 0 [heap]
b4a00000-b4a21000 rw-p b4a00000 00:00 0
b4a21000-b4b00000 ---p b4a21000 00:00 0
b4b2d000-b6a5d000 rw-p b4b2d000 00:00 0
b6a5d000-b6b89000 rw-s 00000000 00:08 3112963 /SYSV00000000 (deleted)
b6b89000-b6b8a000 ---p b6b89000 00:00 0
b6b8a000-b758a000 rw-p b6b8a000 00:00 0
b758a000-b758b000 ---p b758a000 00:00 0
b758b000-b7f8e000 rw-p b758b000 00:00 0
b7fa6000-b7fa9000 rw-p b7fa6000 00:00 0
bff93000-bffa9000 rw-p bff93000 00:00 0 [stack]
/bin/sh: line 1: 27410 Aborted ./mattinggame
BTW, I've changed the code into MyObject **mObject and the object was created by :"mObject = new MyObject[mCount]". It worked fine until a while. When I uncommented a large part of the code, it gone berserk again.
Can anybody help me here?? I'm desperate to a suicidal point here (well, maybe suicidal is a bit too much, but it sure give me a nightmare). Thanks in advance.
Last edited by g4j31a5; August 3rd, 2006 at 06:14 AM.
-
August 3rd, 2006, 06:35 AM
#2
Re: Porting from VC6 to Linux Fedora core 5 problem
Seems like a heap corruption issue.. By the way - can you post the minimal code that replicates the issue on your machine?
Can you help me with my homework assignment?, Before you post!, Use code tags, How to post!, Codeguru technical FAQs, C++ FAQ Lite, Stroustrup: C++ Style and Technique FAQ, Guru of the Week, Comeau C and C++ FAQs, Comeau C++ Templates FAQs, CUJ @ DDJ, Spam threshold
My Blogs : Learning C++ is fun | Abnegator's reflections
Open Threads : C++ Aha! Moments | Nature of work in C++?
-
August 4th, 2006, 02:21 AM
#3
Re: Porting from VC6 to Linux Fedora core 5 problem
Well, I can't give you the full code cause it has already evolving into a "small" giant. Here's a part of it though:
in main
Code:
int main(argc,argv)
{
CImageHandler* mImgHandler; //Object for handling pointer to bitmap images
mImgHandler = new mImgHandler("ImgHandler.cfg"); //Constructor with a filename consisting the names of Bitmap Images
//Objects that will be displayed in the surface
CObjectScene* mObject1;
CObjectScene* mObject2;
CObjectScene* mObject3;
CObjectScene* mObject4;
.... //There's a lot of objects
mObject1 = new CObjectScene(mImgHandler, "Obj1.cfg");
mObject2 = new CObjectScene(mImgHandler, "Obj2.cfg");
mObject3 = new CObjectScene(mImgHandler, "Obj3.cfg");
mObject4 = new CObjectScene(mImgHandler, "Obj4.cfg"); //ERROR here!!!
...... //Other objects constructions
/*
Some rendering loop functions
*/
return 0;
}
in CImageHandler
Code:
typedef map<string, CBmpImage *> lstImage;
typedef lstImage::iterator itrImage;
class CImageHandler
{
public:
//Constructor
CImageHandler(char* filename)
{
char imgname[255], filename[255];
CBmpImage* tempImg;
char buffer[255];
FILE *fp=fopen(filename,"r");
/* Function to extract the configuration of each images from the file. Consist of image's name & image filename*/
while(!feof(fp))
{
fgets(buffer,255,fp);
sscanf(buffer,"%s %s",imgname, filename);
tempImg = new CBmpImage(imgname, filename); //Create & insert image to map
mImages[imgname]=tempImg;
}
fclose(fp);
}
CBmpImage* getImage(string name)
{
return mImages.find(name)->second;
}
private:
lstImage mImages;
}
in the CObjectScene
Code:
struct AnimFrame
{
CBmpImage *theImg;
int delay;
};
typedef vector<AnimFrame *> lstFrames; //List of an animation's frames
typedef lstImage::iterator itrFrames;
class CObjectScene
{
public:
CObjectScene(CImageHandler *imghandler, char* filename)
{
char imgname[255];
int tempdelay;
char buffer[255];
FILE *fp=fopen(filename,"r");
/* Function to extract the configuration of each objects from the file. Consist of image's name & delay to the next frame*/
while(!feof(fp))
{
fgets(buffer,255,fp);
sscanf(buffer,"%s %d",imgname, tempdelay);
AnimFrame *temp = new AnimFrame;
temp->theImg=imghandler->getImage(imgname);
temp->delay=tempdelay;
mFrames.push_back(temp); //ERROR here for the 4th object. The other previous objects are fine.
}
fclose(fp);
}
private:
lstFrames mFrames;
}
Can you help me please?
Last edited by g4j31a5; August 4th, 2006 at 04:40 AM.
-
August 4th, 2006, 02:39 AM
#4
Re: Porting from VC6 to Linux Fedora core 5 problem
I have suspected the cause but I didn't quite sure. In making the CBmpImage objects in CImageHandler, I used this code:
Code:
.....
CBmpImage
{
public:
CBmpImage(char* imgname,char* filename)
{
mName= new char[strlen(imgname)];
strcpy(mName,imgname);
loadBmp(filename);
}
private:
char* mName;
}
.....
I suspected the :
Code:
mName= new char[strlen(imgname)];
strcpy(mName,imgname);
code because I can't delete the mName in the class's destructor. Anybody can give me some enlightment here? Please???
Last edited by g4j31a5; August 4th, 2006 at 04:37 AM.
-
August 4th, 2006, 03:13 AM
#5
Re: Porting from VC6 to Linux Fedora core 5 problem
This is wrong:
Code:
mObject1 = new CObjectScene(mImgHandler, "Obj1.cfg");
mObject1 = new CObjectScene(mImgHandler, "Obj2.cfg");
mObject1 = new CObjectScene(mImgHandler, "Obj3.cfg");
mObject1 = new CObjectScene(mImgHandler, "Obj4.cfg"); //ERROR here!!!
there are leaks - all memory allocations are lost track of because you are using only one pointer to hold them.. correct it. Why are you not using arrays... Or make a collection class of CObjectScene that takes a vector of filenames and creates those many objects and stores them in a internal container. That would encapsulate all the nasty things that you do in main...
Also, use std::string class for holding strings instead of those C-style character arrays... they will remove cases where manually injecting code can cause errors.
Last edited by exterminator; August 4th, 2006 at 03:15 AM.
Can you help me with my homework assignment?, Before you post!, Use code tags, How to post!, Codeguru technical FAQs, C++ FAQ Lite, Stroustrup: C++ Style and Technique FAQ, Guru of the Week, Comeau C and C++ FAQs, Comeau C++ Templates FAQs, CUJ @ DDJ, Spam threshold
My Blogs : Learning C++ is fun | Abnegator's reflections
Open Threads : C++ Aha! Moments | Nature of work in C++?
-
August 4th, 2006, 04:24 AM
#6
Re: Porting from VC6 to Linux Fedora core 5 problem
Here is another problem:
Code:
CImageHandler(char* filename)
{
char imgname[255], filename[255];
You have a parameter called "filename", then you have an array called "filename".
Also, as exterminator pointed out, you can simplify the code greatly if you just stuck with std::string and not introduce char pointers:
Code:
#include <string>
class CBmpImage
{
public:
CBmpImage(const std::string& imgname, const std::string& filename) :
mName( imgname )
{
loadBmp(filename.c_str());
}
private:
std::string mName;
};
You have another problem with the CBmpImage constructor -- what if loadBmp fails? You have an object that is unusable, but it exists anyway and I don't see where you check for failure of loadBmp so as to prevent usage of the bad object.
Also, instead of this:
Code:
//Objects that will be displayed in the surface
CObjectScene* mObject1;
CObjectScene* mObject2;
CObjectScene* mObject3;
CObjectScene* mObject4;
.... //There's a lot of objects
why not do this for your other code:
Code:
#include <cstdio>
#include <vector>
//...
typedef std::vector<CObjectScene *> ObjectSceneArray;
//...
CImageHandler* mImgHandler;
mImgHandler = new mImgHandler("ImgHandler.cfg");
//...
ObjectSceneArray mObject;
char bufname[30];
for ( int i = 1; i <= whatever_number_of_names; ++i )
{
sprintf( bufname, "Obj%d.cfg", i);
mObject.push_back( new CObjectScene( mImgHandler, bufname ) );
}
//...
Regards,
Paul McKenzie
-
August 4th, 2006, 04:34 AM
#7
Re: Porting from VC6 to Linux Fedora core 5 problem
 Originally Posted by exterminator
This is wrong:
Code:
mObject1 = new CObjectScene(mImgHandler, "Obj1.cfg");
mObject1 = new CObjectScene(mImgHandler, "Obj2.cfg");
mObject1 = new CObjectScene(mImgHandler, "Obj3.cfg");
mObject1 = new CObjectScene(mImgHandler, "Obj4.cfg"); //ERROR here!!!
there are leaks - all memory allocations are lost track of because you are using only one pointer to hold them.. correct it. Why are you not using arrays... Or make a collection class of CObjectScene that takes a vector of filenames and creates those many objects and stores them in a internal container. That would encapsulate all the nasty things that you do in main...
Also, use std::string class for holding strings instead of those C-style character arrays... they will remove cases where manually injecting code can cause errors.
oops sorry. I just copy pasted the line. Actually it didn't quite go like that. The objects were all different. I'll edist my post.
-
August 4th, 2006, 04:54 AM
#8
Re: Porting from VC6 to Linux Fedora core 5 problem
 Originally Posted by g4j31a5
I suspected the :
Code:
mName= new char[strlen(imgname)];
strcpy(mName,imgname);
code because I can't delete the mName in the class's destructor. Anybody can give me some enlightment here? Please???
i'd suspect right
Code:
mName= new char[strlen(imgname)+1];
strcpy(mName,imgname);
mName[strlen(imgname)] = '\0';
strlen returns number of char without null termintor...
-
August 4th, 2006, 04:56 AM
#9
Re: Porting from VC6 to Linux Fedora core 5 problem
 Originally Posted by Paul McKenzie
Here is another problem:
Code:
CImageHandler(char* filename)
{
char imgname[255], filename[255];
You have a parameter called "filename", then you have an array called "filename".
Also, as exterminator pointed out, you can simplify the code greatly if you just stuck with std::string and not introduce char pointers:
Code:
#include <string>
class CBmpImage
{
public:
CBmpImage(const std::string& imgname, const std::string& filename) :
mName( imgname )
{
loadBmp(filename.c_str());
}
private:
std::string mName;
};
You have another problem with the CBmpImage constructor -- what if loadBmp fails? You have an object that is unusable, but it exists anyway and I don't see where you check for failure of loadBmp so as to prevent usage of the bad object.
Also, instead of this:
Code:
//Objects that will be displayed in the surface
CObjectScene* mObject1;
CObjectScene* mObject2;
CObjectScene* mObject3;
CObjectScene* mObject4;
.... //There's a lot of objects
why not do this for your other code:
Code:
#include <cstdio>
#include <vector>
//...
typedef std::vector<CObjectScene *> ObjectSceneArray;
//...
CImageHandler* mImgHandler;
mImgHandler = new mImgHandler("ImgHandler.cfg");
//...
ObjectSceneArray mObject;
char bufname[30];
for ( int i = 1; i <= whatever_number_of_names; ++i )
{
sprintf( bufname, "Obj%d.cfg", i);
mObject.push_back( new CObjectScene( mImgHandler, bufname ) );
}
//...
Regards,
Paul McKenzie
Thanks, I've tried it and it worked. The error is gone. Thank GOD!!! But another problem though (a warning actually), in this code:
Code:
void loadBmp(std:string fullname)
{
if (!(myPic = SDL_LoadBMP(fullName)))
{
printf("ERROR opening file %s\n\n", fullName);
exit(1);
}
}
The printf doesn't work because the parameter is an std::string. Well not that it matters (it's only a warning), but it is somewhat pesky.
-
August 4th, 2006, 05:08 AM
#10
Re: Porting from VC6 to Linux Fedora core 5 problem
 Originally Posted by g4j31a5
The printf doesn't work because the parameter is an std::string. Well not that it matters (it's only a warning), but it is somewhat pesky.
Your code would exhibit undefined behavior, and possibly crash. The "%s" format specifier is looking for a char buffer, and a std::string isn't a char buffer.
You need to use the c_str() member function that returns a const char * in the printf():
Code:
void loadBmp(const std:string& fullname) // Note passed by const reference
{
if (!(myPic = SDL_LoadBMP(fullName)))
{
printf("ERROR opening file %s\n\n", fullName.c_str());
exit(1);
}
}
Also, pass strings by reference (if they are changed within the function) or const reference (if they are not changed in the function). Passing std::string by value (as your code did) may result in a performance hit.
Regards,
Paul McKenzie
-
August 6th, 2006, 08:49 PM
#11
Re: Porting from VC6 to Linux Fedora core 5 problem
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|