Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Malloc fails...why?

Malloc fails...why?

Scheduled Pinned Locked Moved C / C++ / MFC
csharpvisual-studiojsonquestion
8 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    damir_tk
    wrote on last edited by
    #1

    I don't understand why this fails: LPTSTR FileHelper::GetFileFullPath( LPWSTR lpwName ) { LPTSTR lptFileFullPath; DWORD len = GetCurrentDirectory( 0, NULL ); LPWSTR lpwFolder; lpwFolder = (LPWSTR) malloc( len ); if ( lpwFolder == NULL ) { free ( lpwFolder ); return NULL; } if ( GetCurrentDirectory( len, lpwFolder ) != 0 ) { len = (DWORD) ( wcslen( lpwFolder ) + wcslen( lpwName ) + 6 ); lptFileFullPath = (LPTSTR) malloc( len ); // Here lptFileFullPath simply evaluates to NULL, showing the ?! if ( lptFileFullPath == NULL ) { free ( lptFileFullPath ); return NULL; } // ...the rest of the code stripped off... } return lptFileFullPath; } This is under Visual Studio 2005, UNICODE defined by default. Thanks.

    T W M 3 Replies Last reply
    0
    • D damir_tk

      I don't understand why this fails: LPTSTR FileHelper::GetFileFullPath( LPWSTR lpwName ) { LPTSTR lptFileFullPath; DWORD len = GetCurrentDirectory( 0, NULL ); LPWSTR lpwFolder; lpwFolder = (LPWSTR) malloc( len ); if ( lpwFolder == NULL ) { free ( lpwFolder ); return NULL; } if ( GetCurrentDirectory( len, lpwFolder ) != 0 ) { len = (DWORD) ( wcslen( lpwFolder ) + wcslen( lpwName ) + 6 ); lptFileFullPath = (LPTSTR) malloc( len ); // Here lptFileFullPath simply evaluates to NULL, showing the ?! if ( lptFileFullPath == NULL ) { free ( lptFileFullPath ); return NULL; } // ...the rest of the code stripped off... } return lptFileFullPath; } This is under Visual Studio 2005, UNICODE defined by default. Thanks.

      T Offline
      T Offline
      Taka Muraoka
      wrote on last edited by
      #2

      I think your first malloc is wrong. "len" is the length of the current directory in characters but malloc() takes a number of bytes i.e. it should be sizeof(TCHAR) * len.


      0 bottles of beer on the wall, 0 bottles of beer, you take 1 down, pass it around, 4294967295 bottles of beer on the wall. Awasu 2.2.3 [^]: A free RSS/Atom feed reader with support for Code Project.

      1 Reply Last reply
      0
      • D damir_tk

        I don't understand why this fails: LPTSTR FileHelper::GetFileFullPath( LPWSTR lpwName ) { LPTSTR lptFileFullPath; DWORD len = GetCurrentDirectory( 0, NULL ); LPWSTR lpwFolder; lpwFolder = (LPWSTR) malloc( len ); if ( lpwFolder == NULL ) { free ( lpwFolder ); return NULL; } if ( GetCurrentDirectory( len, lpwFolder ) != 0 ) { len = (DWORD) ( wcslen( lpwFolder ) + wcslen( lpwName ) + 6 ); lptFileFullPath = (LPTSTR) malloc( len ); // Here lptFileFullPath simply evaluates to NULL, showing the ?! if ( lptFileFullPath == NULL ) { free ( lptFileFullPath ); return NULL; } // ...the rest of the code stripped off... } return lptFileFullPath; } This is under Visual Studio 2005, UNICODE defined by default. Thanks.

        W Offline
        W Offline
        Waldermort
        wrote on last edited by
        #3

        First, why are you not using new and delete? and second, why are you calling free() on what you already know to be a NULL pointer? Now for your problem, GetCurrentDirectory() is returning the length required excluding the terminating NULL character, but you are not adding this when you call malloc. so your second call will read the string and not write the NULL. Later when you call wstrlen(), it is reading the string uo until the first NULL it finds, which could be anywhere. Therefore may return an insanly high value. When used in malloc, it returns NULL because there is not enough memory. The problem has nothing to do with sizeof(TCHAR) ;P

        D 1 Reply Last reply
        0
        • D damir_tk

          I don't understand why this fails: LPTSTR FileHelper::GetFileFullPath( LPWSTR lpwName ) { LPTSTR lptFileFullPath; DWORD len = GetCurrentDirectory( 0, NULL ); LPWSTR lpwFolder; lpwFolder = (LPWSTR) malloc( len ); if ( lpwFolder == NULL ) { free ( lpwFolder ); return NULL; } if ( GetCurrentDirectory( len, lpwFolder ) != 0 ) { len = (DWORD) ( wcslen( lpwFolder ) + wcslen( lpwName ) + 6 ); lptFileFullPath = (LPTSTR) malloc( len ); // Here lptFileFullPath simply evaluates to NULL, showing the ?! if ( lptFileFullPath == NULL ) { free ( lptFileFullPath ); return NULL; } // ...the rest of the code stripped off... } return lptFileFullPath; } This is under Visual Studio 2005, UNICODE defined by default. Thanks.

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          I would recommend looking VERY closely at all the string functions you use. Some use/return lengths in characters. Some use/return lengths in bytes. Some include NULL terminator in lengths. Some do not. LPTSTR FileHelper::GetFileFullPath( LPWSTR lpwName ) { LPTSTR lptFileFullPath; DWORD LenInChars = GetCurrentDirectory( 0, NULL ); ++LenInChars; // add 1 for NULL terminator LPWSTR lpwFolder; lpwFolder = (LPWSTR) malloc( LenInChars * sizeof(TCHAR) ); if ( lpwFolder == NULL ) { return NULL; // or throw new CIScrewedUpException(); } if ( GetCurrentDirectory( LenInChars, lpwFolder ) != 0 ) { // added 1 for NULL terminator LenInChars = (DWORD) ( wcslen( lpwFolder ) + wcslen( lpwName ) + 1 ); lptFileFullPath = (LPTSTR) malloc( LenInChars * sizeof(TCHAR)); // Here lptFileFullPath simply evaluates to NULL, showing the ?! if ( lptFileFullPath == NULL ) { // prevent memory leak free( lpwFolder ); return NULL; } // ...the rest of the code stripped off... } // prevent memory leak free( lpwFolder ); return lptFileFullPath; } *EDIT* And for goodness sakes, use new/delete instead of malloc/free!!! :)

          D 1 Reply Last reply
          0
          • W Waldermort

            First, why are you not using new and delete? and second, why are you calling free() on what you already know to be a NULL pointer? Now for your problem, GetCurrentDirectory() is returning the length required excluding the terminating NULL character, but you are not adding this when you call malloc. so your second call will read the string and not write the NULL. Later when you call wstrlen(), it is reading the string uo until the first NULL it finds, which could be anywhere. Therefore may return an insanly high value. When used in malloc, it returns NULL because there is not enough memory. The problem has nothing to do with sizeof(TCHAR) ;P

            D Offline
            D Offline
            damir_tk
            wrote on last edited by
            #5

            Thanks, you are totally right.

            1 Reply Last reply
            0
            • M Mark Salsbery

              I would recommend looking VERY closely at all the string functions you use. Some use/return lengths in characters. Some use/return lengths in bytes. Some include NULL terminator in lengths. Some do not. LPTSTR FileHelper::GetFileFullPath( LPWSTR lpwName ) { LPTSTR lptFileFullPath; DWORD LenInChars = GetCurrentDirectory( 0, NULL ); ++LenInChars; // add 1 for NULL terminator LPWSTR lpwFolder; lpwFolder = (LPWSTR) malloc( LenInChars * sizeof(TCHAR) ); if ( lpwFolder == NULL ) { return NULL; // or throw new CIScrewedUpException(); } if ( GetCurrentDirectory( LenInChars, lpwFolder ) != 0 ) { // added 1 for NULL terminator LenInChars = (DWORD) ( wcslen( lpwFolder ) + wcslen( lpwName ) + 1 ); lptFileFullPath = (LPTSTR) malloc( LenInChars * sizeof(TCHAR)); // Here lptFileFullPath simply evaluates to NULL, showing the ?! if ( lptFileFullPath == NULL ) { // prevent memory leak free( lpwFolder ); return NULL; } // ...the rest of the code stripped off... } // prevent memory leak free( lpwFolder ); return lptFileFullPath; } *EDIT* And for goodness sakes, use new/delete instead of malloc/free!!! :)

              D Offline
              D Offline
              damir_tk
              wrote on last edited by
              #6

              Haha...okay, I like your style (both of writing and of coding), and thanks for your help. Now 3 questions: 1. Why malloc sucks, I don't see any problems with it. New and delete is better when you are creating some objects that have a constructor and a destructor, as they get called automatically, but not if you use malloc. But here I only use strings and string pointers, so why? 2. I already rewrite the code, to use something like: lpwFolder = (LPWSTR) malloc( (len + 1) * 2 ); Is it wrong? (Apart from not being elegant :=) ). 3. I use _tcslen instead of wcslen, is it better suited here? Thanks for your help again.

              M 1 Reply Last reply
              0
              • D damir_tk

                Haha...okay, I like your style (both of writing and of coding), and thanks for your help. Now 3 questions: 1. Why malloc sucks, I don't see any problems with it. New and delete is better when you are creating some objects that have a constructor and a destructor, as they get called automatically, but not if you use malloc. But here I only use strings and string pointers, so why? 2. I already rewrite the code, to use something like: lpwFolder = (LPWSTR) malloc( (len + 1) * 2 ); Is it wrong? (Apart from not being elegant :=) ). 3. I use _tcslen instead of wcslen, is it better suited here? Thanks for your help again.

                M Offline
                M Offline
                Mark Salsbery
                wrote on last edited by
                #7

                damir_tk wrote:

                1. Why malloc sucks, I don't see any problems with it. New and delete is better when you are creating some objects that have a constructor and a destructor, as they get called automatically, but not if you use malloc. But here I only use strings and string pointers, so why?

                I didn't say it sucks ;) You're using C++ so why not take advantage of the much stronger type safety provided by the language? Using "new", you create a typed pointer so the compiler can help point out mistakes during development because it knows the pointers type without having to use the old C-style cast. Use what you want, of course, but I bet you'll find new and delete much more pleasing to use.

                damir_tk wrote:

                2. I already rewrite the code, to use something like: lpwFolder = (LPWSTR) malloc( (len + 1) * 2 ); Is it wrong? (Apart from not being elegant :=) ). 3. I use _tcslen instead of wcslen, is it better suited here?

                The only thing I see that's not elegant is mixing the generic "T" types with the hard-coded "W" types. By using the "T" types you have the advantage of your code working for both UNICODE and non-UNICODE builds. It also fits the way the Windows APIs are declared. If you know you are only ever going to use UNICODE then you could just use the "W" string types. It's just easier to read the code if you stick to one set of types and functions. This is all just my opinions of course. :) Here's another version of your code using all "T" char types and new/delete...

                LPTSTR FileHelper::GetFileFullPath( LPCTSTR lpwName )
                {
                	LPTSTR lptFileFullPath;
                	DWORD LenInChars = ::GetCurrentDirectory( 0, NULL );
                	++LenInChars; // add 1 for NULL terminator
                	LPTSTR lpwFolder = new TCHAR[ LenInChars ];
                	if ( lpwFolder == NULL )
                	{
                		return NULL;
                	}
                	if ( ::GetCurrentDirectory( LenInChars, lpwFolder ) != 0 )
                	{
                		// I added 6 like you did before...you may need more chars for backslashes and such
                		LenInChars = (DWORD)( _tcslen( lpwFolder ) + _tcslen( lpwName ) + 6 );
                		lptFileFullPath = new TCHAR[ LenInChars ];
                		if ( lptFileFullPath == NULL )
                		{
                			// prevent memory leak
                			delete[] lpwFolder;
                			return NULL;
                		}
                		// ...the rest of the code stripped off...
                	}
                	// prevent memory leak
                	delete[] lpwFolder;
                	return lptFileFullPath;
                }
                
                D 1 Reply Last reply
                0
                • M Mark Salsbery

                  damir_tk wrote:

                  1. Why malloc sucks, I don't see any problems with it. New and delete is better when you are creating some objects that have a constructor and a destructor, as they get called automatically, but not if you use malloc. But here I only use strings and string pointers, so why?

                  I didn't say it sucks ;) You're using C++ so why not take advantage of the much stronger type safety provided by the language? Using "new", you create a typed pointer so the compiler can help point out mistakes during development because it knows the pointers type without having to use the old C-style cast. Use what you want, of course, but I bet you'll find new and delete much more pleasing to use.

                  damir_tk wrote:

                  2. I already rewrite the code, to use something like: lpwFolder = (LPWSTR) malloc( (len + 1) * 2 ); Is it wrong? (Apart from not being elegant :=) ). 3. I use _tcslen instead of wcslen, is it better suited here?

                  The only thing I see that's not elegant is mixing the generic "T" types with the hard-coded "W" types. By using the "T" types you have the advantage of your code working for both UNICODE and non-UNICODE builds. It also fits the way the Windows APIs are declared. If you know you are only ever going to use UNICODE then you could just use the "W" string types. It's just easier to read the code if you stick to one set of types and functions. This is all just my opinions of course. :) Here's another version of your code using all "T" char types and new/delete...

                  LPTSTR FileHelper::GetFileFullPath( LPCTSTR lpwName )
                  {
                  	LPTSTR lptFileFullPath;
                  	DWORD LenInChars = ::GetCurrentDirectory( 0, NULL );
                  	++LenInChars; // add 1 for NULL terminator
                  	LPTSTR lpwFolder = new TCHAR[ LenInChars ];
                  	if ( lpwFolder == NULL )
                  	{
                  		return NULL;
                  	}
                  	if ( ::GetCurrentDirectory( LenInChars, lpwFolder ) != 0 )
                  	{
                  		// I added 6 like you did before...you may need more chars for backslashes and such
                  		LenInChars = (DWORD)( _tcslen( lpwFolder ) + _tcslen( lpwName ) + 6 );
                  		lptFileFullPath = new TCHAR[ LenInChars ];
                  		if ( lptFileFullPath == NULL )
                  		{
                  			// prevent memory leak
                  			delete[] lpwFolder;
                  			return NULL;
                  		}
                  		// ...the rest of the code stripped off...
                  	}
                  	// prevent memory leak
                  	delete[] lpwFolder;
                  	return lptFileFullPath;
                  }
                  
                  D Offline
                  D Offline
                  damir_tk
                  wrote on last edited by
                  #8

                  Thank a lot. Point taken. :)

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups