Code:
#include <stdlib.h> /* Used for standard C/C++ operations. */
#include <limits.h> /* Used to get the defined system limits. */
#include <unistd.h> /* Used for pathconf, _PC_PATH_MAX. */
#include <string.h> /* Used for string operations like strcpy and memset */
#include <sys/dirent.h> /* Used for directory structures and operations. */
#include <sys/types.h> /* Used for primitive system types. */
#include <sys/stat.h> /* Used for stat structures and stat operations. */
#include <vector> /* Used for vector data structures. */
/////////////////////////////////////////////////////////////////////////////////////
// PROTOTYPES //
/////////////////////////////////////////////////////////////////////////////////////
typedef int get_pt ( const char *, const struct stat *, int );
static get_pt get_path_type;
static int get_path ( const char *, get_pt * );
static int parse_path ( get_pt * );
/////////////////////////////////////////////////////////////////////////////////////
// DEFINES //
/////////////////////////////////////////////////////////////////////////////////////
#define FTW_F 1 /* file other than directory */
#define FTW_D 2 /* directory */
#define FTW_DNR 3 /* directory cannot be read */
#define FTW_NS 4 /* file we cannot stat */
/////////////////////////////////////////////////////////////////////////////////////
// GLOBALS //
/////////////////////////////////////////////////////////////////////////////////////
const char *TOP_DIR = "/dev";
static char *FULLPATH;
vector<char *> vdevice;
vector<int> vmajor;
vector<int> vminor;
int main ( void ) {
ret = get_path( TOP_DIR, get_path_type );
for ( auto unsigned int i = 0; i < vdevice.size(); i++ ) {
printf( "%s %d %06x\n", (vdevice.at(i)).c_str(), vmajor.at(i), vminor.at(i) );
}
for ( i = vdevice.size(); i > 0; --i ) {
printf( "DELETING [%d] [%i]\n", vdevice.size(), (i - 1) );
delete vdevice.at( i -1 ); // <--------------MEMORY LEAK
}
}
static int get_path ( const char *ptrPathname, get_pt *gpt ){
////////////////////////////////////////////////////////////////////
// Entry point into the rest of the logic. //
////////////////////////////////////////////////////////////////////
int ret = 0;
FULLPATH = new char [ ( pathconf( "/", _PC_PATH_MAX ) + 1 ) ];
memset( FULLPATH, 0, sizeof( FULLPATH ) );
strcpy( FULLPATH, ptrPathname );
ret = parse_path( gpt );
if ( FULLPATH ) {
delete [] FULLPATH;
}
return ( ret );
}
static int parse_path ( get_pt *gpt ) {
////////////////////////////////////////////////////////////////////////////////////
// Descend through the hierarchy, starting at "fullpath". If "fullpath" is //
// anything other than a directory, then lstat() it, call get_path_type [gpt], and//
// return. For a directory, we call ourself ( parse_path ) recursively for each //
// name in the directory. //
////////////////////////////////////////////////////////////////////////////////////
struct stat statbuf;
struct dirent *ptrDir;
DIR *ptrD;
int ret;
char *ptr;
(void)memset( &statbuf, 0, sizeof( struct stat ) );
if ( lstat( FULLPATH, &statbuf ) < 0 ) {
return( gpt( FULLPATH, &statbuf, FTW_NS ) ); /* lstat error */
}
if ( S_ISDIR( statbuf.st_mode ) == 0 ) {
return( gpt( FULLPATH, &statbuf, FTW_F ) ); /* not a directory */
}
if ( ( ret = gpt( FULLPATH, &statbuf, FTW_D ) ) != 0 ) {
return( ret );
}
ptr = FULLPATH + strlen( FULLPATH ); /* point to the end of FULLPATH */
*ptr++ = '/';
*ptr = 0;
if ( ( ptrD = opendir( FULLPATH ) ) == NULL ) {
return ( gpt( FULLPATH, &statbuf, FTW_DNR ) ); /* Cannot read directory */
}
while ( ( ptrDir = readdir( ptrD ) ) != NULL ) {
if ( strcmp( ptrDir->d_name, "." ) == 0 |
strcmp( ptrDir->d_name, ".." ) == 0 |
strcmp( ptrDir->d_name, "group" ) == 0 ) {
continue; /* ignore dot ".", dot dot ".." and group */
}
strcpy( ptr, ptrDir->d_name ); /* append name after slash */
if ( ( ret = parse_path( gpt ) ) != 0 ) { break; } /* recursive */
}
ptr[-1] = 0; /* erase everything from slash onward */
if ( closedir( ptrD ) < 0 ) {
printf ( "ERROR: Cannot close directory %s", FULLPATH );
}
if ( ptrDir ) {
delete [] ptrDir;
}
return ( ret );
}
static int get_path_type( const char *ptrPathname, const struct stat *ptrStat, int type ) {
//////////////////////////////////////////////////////////////////////
// If I used string and put it into the vector it does not leak. //
// string s;
// auto unsigned int i =0;
char *s = new char [ ( pathconf( "/", _PC_PATH_MAX ) +1 ) ];
memset( s, 0, sizeof( s ) );
strcpy( s, ptrPathname );
switch (type) {
case FTW_F:
switch( ptrStat->st_mode & S_IFMT ) {
case S_IFBLK:
//for ( i =0; i < strlen( ptrPathname ); i++ ) { s += ptrPathname[i]; }
vdevice.push_back( s );
vmajor.push_back( (int)major(ptrStat->st_rdev) );
vminor.push_back( (int)minor(ptrStat->st_rdev) );
break;
case S_IFCHR:
//for ( i =0; i < strlen( ptrPathname ); i++ ) { s += ptrPathname[i]; }
vdevice.push_back( s );
vmajor.push_back( (int)major(ptrStat->st_rdev) );
vminor.push_back( (int)minor(ptrStat->st_rdev) );
break;
//////////////////////////////////////////////////////////////////////
// CODE REMOVED TO PREVENT BOREDOME //
//////////////////////////////////////////////////////////////////////
default:
printf ( "ERROR: unknown type %d for path %s\n", type, ptrPathname );
break;
}
return ( 0 );
}
I cannot seem to figure out why it is considered a memory leak whan I take place "ptrPathname" into "s" and then push "s" into vector "vdevice", I am then setting up a potential memory leak.