CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2006
    Posts
    14

    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.

  2. #2
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    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?

  3. #3
    Join Date
    Aug 2006
    Posts
    14

    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.

  4. #4
    Join Date
    Aug 2006
    Posts
    14

    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.

  5. #5
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    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.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    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

  7. #7
    Join Date
    Aug 2006
    Posts
    14

    Re: Porting from VC6 to Linux Fedora core 5 problem

    Quote 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.

  8. #8
    Join Date
    Aug 2006
    Posts
    16

    Re: Porting from VC6 to Linux Fedora core 5 problem

    Quote 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...

  9. #9
    Join Date
    Aug 2006
    Posts
    14

    Re: Porting from VC6 to Linux Fedora core 5 problem

    Quote 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.

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Porting from VC6 to Linux Fedora core 5 problem

    Quote 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

  11. #11
    Join Date
    Aug 2006
    Posts
    14

    Re: Porting from VC6 to Linux Fedora core 5 problem

    Thanks a lot.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured