Search code examples
c++chardelete-operatorargs

C++ Delete char**


I know there have been many questions about this but I have tried everything and NOTHING seems to be working.

I have char** and when I try to delete it, I get exception thrown. When I do not delete it, an exception is thrown after the function returns.

I have a function similar to this:

void function(){
     int argc = 5; char** argv;
     argv[0] = "...";
     argv[1] = "...";
     //...
     Package package;
     package.ProcessCommandLineArgs(argc, argv); // this does NOT delete argv

     // THIS FAILS
     for(int i=0;i<5;i++) 
         delete[] argv[i]; // <--- EXCEPTION HERE
     delete[] argv;
}

I have even tried using the function only with this:

void function(){
     int argc = 5; char** argv;
     argv[0] = "...";
     argv[1] = "...";
     //...

     // just declare argv and delete it also fails
     for(int i=0;i<5;i++) 
         delete[] argv[i]; // <--- EXCEPTION HERE
     delete[] argv;
}

I cannot not use char** as I have 4 classes that use the same arguments in a chain of calls so I do not have the option to use vector<string>.

I would appreciate any help. If you want to vote down, do it, but please give me an answer as I have been stumbling with this for hours.

Thanks.

EDIT: I see why this got down-voted and right now I would down-vote it if I had seen it asked on SO. I have since changed all my programs to convert arguments into std::vector<std::string>. If I attempt to delete this question I will be at risk of losing my ability to ask questions since this already has an answer.


Solution

  • A version of your code that might work is something like this:

    #define MAX_SIZE 256 // TODO: set to the size you need...
    void function(){
         int argc = 5;
         char** argv = new char*[argc]; // allocate space for the array!
         for(int i = 0; i < argc; ++i) {
             argv[i] = new char[MAX_SIZE];  // allocate space for the array entry!
         }
    
         // TODO: bounds checking!!!
         strcpy(argv[0], "...");     // set the string to the "..."
         strcpy(argv[1], "...");     // same...
    
    
    
         // cleanup
         for(int i=0;i<argc;i++) 
             delete[] argv[i];
         delete[] argv;
    }
    

    In short, only delete[] what you new[], only delete what you new and only free what you malloc/calloc/realloc.

    That being said, if you have control over the implementation of ProcessCommandLineArgs, it would be far superior to just pass a std::vector<std::string> and just not worry about the memory management.