24

I need a cross-platform way to get the current working directory (yes, getcwd does what I want). I thought this might do the trick:

#ifdef _WIN32
    #include <direct.h>
    #define getcwd _getcwd // stupid MSFT "deprecation" warning
#elif
    #include <unistd.h>
#endif
#include <string>
#include <iostream>
using namespace std;

int main()
{
    string s_cwd(getcwd(NULL,0));
    cout << "CWD is: " << s_cwd << endl;
}

I got this reading:

There should be no memory leaks, and it should work on a Mac as well, correct?

UPDATE: I fear something is still wrong here (I'm trying to avoid creating a char array with a determined length, as there's no proper way to get a decent length for getcwd):

char* a_cwd = getcwd(NULL,0);
string s_cwd(a_cwd);
free(a_cwd); // or delete a_cwd? 
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
rubenvb
  • 74,642
  • 33
  • 187
  • 332

3 Answers3

28

If it is no problem for you to include, use boost filesystem for convenient cross-platform filesystem operations.

boost::filesystem::path full_path( boost::filesystem::current_path() );

Here is an example.

EDIT: as pointed out by Roi Danton in the comments, filesystem became part of the ISO C++ in C++17, so boost is not needed anymore:

std::filesystem::current_path();
catchmeifyoutry
  • 7,179
  • 1
  • 29
  • 26
14

You cannot call getcwd with a NULL buffer. As per the Opengroup:

If buf is a null pointer, the behavior of getcwd() is unspecified.

Also, getcwd can return NULL which can break a string constructor.

You'll need to change that to something like:

char buffer[SIZE];
char *answer = getcwd(buffer, sizeof(buffer));
string s_cwd;
if (answer)
{
    s_cwd = answer;
}
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
  • 4
    If he's "only" interested in compatibility with Windows, Linux, and Max OS X, then `getcwd(NULL)` is well defined. They all extend the function the same way. – Rob Kennedy May 19 '10 at 19:35
  • 1
    I accepted this, but the above comment is imho correct. My code did have a memory leak though, so that needs solving – rubenvb May 19 '10 at 20:07
  • @RobKennedy - for Linux, it depends on the version being targeted. For example, on a RHEL5 box, the `getcwd(NULL)` is still documented as being undefined. – R Samuel Klatchko May 19 '10 at 21:13
  • Good luck using this on Windows with Unicode characters in the path. – rustyx Aug 31 '17 at 19:43
3

Calling getcwd with a NULL pointer is implementation defined. It often does the allocation for you with malloc (in which case your code does have a memory leak). However, it isn't guaranteed to work at all. So you should allocate your own buffer.

char *cwd_buffer = malloc(sizeof(char) * max_path_len);
char *cwd_result = getcwd(cwd_buffer, max_path_len);

The Open Group has an example showing how to get the max path length from _PC_PATH_MAX. You could consider using MAX_PATH on Windows. See this question for caveats to this number on both platforms.

Community
  • 1
  • 1
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539