5
votes

I have a class as follows

 struct CliHandler {
     CliHandler(int argc, char** argv);
     ~CliHandler();

     int doWork();

     int argc_; 
     char** argv_;  
     private:
     CliHandler(const CliHandler&){}
     CliHandler& operator=(const CliHandler&){} 
 };

//Constructor

 CliHandler::CliHandler(int argc,
 char** argv) {
     //set command line parameters
     argc_ = argc; 

     argv_ = (char**) malloc(argc_ * sizeof(char*));

     for(int i=0; i<argc_; ++i)
     {
         std::cout<<sizeof(argv[i]); 
         argv_[i] = (char*) malloc(strlen(argv[i]) *
 sizeof(char));
         StrCpy(argv_[i], argv[i]);
     } }

// destructor

 CliHandler::~CliHandler() {
     for(int i=0; i<argc_; ++i)
         free(argv_[i]); 
     free(argv_);  }

While I debug, I get an error " Heap corruption detected. CRT detected that application wrote to memory after end of heap buffer. " My question id "Where exactly am i making a mistake ? How do I fix it". I am using visual stdio 2008.

Edit:I did something like this to add 1

argv_[i] = (char*) malloc(strlen(argv[i] + 1) * sizeof(char));

Which is terrible as it increments the pointer argv[i] by one. My co-worker pointed out that subtle issue. It should be

argv_[i] = (char*) malloc( (strlen(argv[i]) + 1) * sizeof(char));

4
One thing that I see is that you don't allocate space for the null-terminator. Should be strlen(argv[i]) + 1. - Marius Bancila
Why, if you are using C++, are you using malloc? And why are you not using std:;vector and std::string? - user2100815
Another potential problem I see is that you don't follow the Rule of Three. If any copying happens, you're in trouble. - Fred Larson
@unapersson - i'm integrating some function with legacy code. - Eternal Learner
So what? The things you allocate to are private, so they can't be used directly by the legacy code, so you could (and should) implement them using vectors and strings. Otherwise, you are simply writing MORE legacy code. - user2100815

4 Answers

8
votes

Change the code to:

 argv_[i] = (char*) malloc(strlen(argv[i]) + 1) ; 
 strcpy(argv_[i], argv[i]); 

It's because your StrCpy likely trashes your memory. You have to account for the terminating nul byte as well, provided your StrCpy works like the standard strcpy (which it has to in order to be useful, better just use the standard strcpy() unless you have a good reason not to).

sizeof(char) is by definition 1, so that can be omitted too.

1
votes

You need to allocate one character more than the strlen of a C-string if you want to copy it. This is because strlen does not count the termination null-character.

1
votes

Please use strdup() - it allocates the right amount of memory and copies characters for you.

0
votes

If StrCpy is anything like strcpy, it will write one byte more than strlen() returns, to zero terminate the string.