how can i handle an invalid exception handler routine?

3

I'm building a program, that creates and deletes directories. I use the MSVC compiler (Visual Studio 2017), which is the reason i can't use "getcwd()" or "dirent.h" respectively. I have tried several different ways to get the current working directory, but there was always a problem. I managed to print the cwd with "_wgetcwd()". However I couldn't find how I could convert it's output to use it in "_rmdir()" or "_wrmdir()" in my research.

My main goal is to be able to remove a directory without having to install some new compiler. If this condition is met, any help is appreciated, because I already tried to install a different Compiler, but I didn't got it to work. I also tried different ways to get the cwd and convert it into the desired datatype, but nothing worked with the scope of my IDE and my very basic knowledge.

I'm pretty much a beginner in programming and I'm learning with this book, that unfortunately uses "dirent.h". The following is a snippet of my current code, where I have eradicated all errors. However I still get this last annoying exception:

#include <iostream>
#include <stdlib.h>
#include<string>
#include <direct.h>

int main() {

    int t = 0;
    std::string str;
    char xy = ' ';
    char* _DstBuf = &xy;
    const char* uniquename;
    uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);
    std::cout << "Current path is ";    
    while (*uniquename != '\0') // this pointer points to the beginning of my path
    {
        std::cout << char(*uniquename); //  prints one char of the path name for each iteration

        char var = char(*uniquename);

        str.push_back(var); //here the exception below is thrown.

        // jump to the next block of memory
        uniquename++;
    }
    std::cout << str <<'\n';

    const char* lastchance = str.c_str();

    if (_wchdir('..')) {
        std::cout << "changing directory failed.\n";
    }

    if (_rmdir(lastchance) == -1 && errno == ENOTEMPTY) { 
        std::cout << "Given path is not a directory, the directory is not empty, or the directory is either the current working directory or the root directory.\n";
    }
    else if (_rmdir(lastchance) == -1 && errno == ENOENT) 
    {
        std::cout << "Path is invalid.\n";
    }
    else if (_rmdir(lastchance) == -1 && errno == EACCES)
    {
        std::cout << "A program has an open handle to the directory.\n";
    }
    else if (_rmdir(lastchance)) {
        std::cout << "removing directory still not possible\n";
    }

}

This is the exception I get: Unhandled exception at 0x6E656D69 in Experimentfile.exe: 0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000003).

c++
exception
visual-c++
asked on Stack Overflow Apr 13, 2020 by federico Mejia

2 Answers

3

So if you are going to program in a C style (even though you have a C++ compiler) you're going to have to learn how arrays and pointers work. It's far too big a topic to learn from the internet you need a good book.

However I'll point out some of the errors

char xy = ' ';
char* _DstBuf = &xy;
const char* uniquename;
uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);

This is just hopelessly wrong. It compiles but that doesn't mean it's going to work. This is what's required

char DstBuf[_MAX_PATH];
_getdcwd(0, DstBuf, _MAX_PATH);

_getdcwd requires an array which is passed as a pointer (see, you need to learn about arrays and pointers).

Then you attempt to print out the result and assign the result to a string. Again the code is way more complex than it needs to be. Here's the simpler version

std::string str = DstBuf;
std::cout << str <<'\n';

Then you attempt to change directories. I don't know why you are using the wide version _wchdir when you have narrow strings, use _chdir instead. And again the parameter is incorrect, '..' is a multi character literal, but _chdir requires a C-string. Here's the correct verison using _chdir.

if (_chdir("..")) {
    std::cout << "changing directory failed.\n";
} 

Then you try to remove a directory four times, obviously you can't remove a directory more than once.

And so on, and so on.

answered on Stack Overflow Apr 13, 2020 by john • edited Apr 13, 2020 by john
2

There are several problems with your code. I think your exception is caused by this line:

uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);

Which is calling _getdcwd and passing it a pointer to a single character, while also specifying that the pointer can hold up to _MAX_PATH. This is completely undefined behaviour.

To fix this issue I think you should completely change what you are doing. Your code reads like C code, apart from the scattered C++ parts like std::string. Since C++17 the standard library has support for filesystem manipulation built in. Therefore you can rewrite your code using std::filesystem in a much more concise and safe way.

... // get path to delete and store it in del_path (del_path should be an std::filesystem::path object)
std::filesystem::remove_directories(del_path); // Recursive delete the directory specified by del_path
...

Note: std::filesystem::remove_directories will throw an std::filesystem::filesystem_error if it fails.

You can obtain the current directory using std::filesystem through std::filesystem::current_path.

I also recommend picking up a better book on C++ since this one does not seem to be teaching you good practices

answered on Stack Overflow Apr 13, 2020 by Firefly

User contributions licensed under CC BY-SA 3.0