简体   繁体   中英

deleting char ** correctly?

I've created a 2d array of c-strings using :

char ** my_array = new char*[N];

and then I initialized each row using :

my_array[i] = new char[M]; // where M is a varying number. assign values to my_array[i] later

So I pretty much got a jagged 2d array.

I wanted to proceed and delete the whole thing like this :

for(int i = 0; i < N; i++)
{ delete [] my_array[i]; }

followed by a :

delete [] my_array;

the for loop gave me HEAP CORRUPTION ERROR - why?

************** UPDATE - full code *********************

#define BOOST_TEST_MODULE ARGS
#define BOOST_LIB_DIAGNOSTIC

#include <string>
#include <vector>
#include <iostream>
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/assign.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/assign/std/vector.hpp>

using namespace std;
using namespace boost;
using namespace boost::assign;

typedef vector<string> string_array;

BOOST_AUTO_TEST_CASE(test1)
{
    string_array args = list_of
        ("aaa")("bbbb")("ccccccc")("dd")("eeeeeeeee")("ff")("g")("hhh");

    string_array tokens;

    string arg = "";
    for(int i = 0; i < (int)args.size(); i++)
    {
        arg += args[i];
        if(i != (int)args.size() - 1)
                arg += " ";
    }

    split(tokens, arg, is_any_of(" "));

    char ** new_args = NULL;
    new_args = new char*[(int)tokens.size() + 1];
    new_args[(int)tokens.size()] = 0;
    for(int i = 0; i < (int)tokens.size(); i++)
    { 
        new_args[i] = new char[(int)tokens[i].size()];
        for(int j = 0; j <= (int)tokens[i].size(); j++)
        {
            if(j == (int)tokens[i].size())
                new_args[i][j] = '\0';
            else
                new_args[i][j] = tokens[i][j];

        }
    }

    for(int i = 0; i < (int)tokens.size(); i++)
    { 
        std::cout << new_args[i] << std::endl; 
    }

    for(int i = (int)tokens.size() - 1; i >= 0; i--)
        delete new_args[i]; 

    delete [] new_args;
}

If you don't have boost installed : convert the BOOST_AUTO_TEST_CASE to main() and voil'a.

What the above thing does : converts a vector into char **

Your code appears to be correct. Chances are that your heap corruption is caused by some other code, and is only detected when this deallocation code is run.

You can check this by running the above code in isolation, without any other code around it. You should be able to verify that there is no heap corruption from this.

Depending on your development environment, turn up all the memory allocation checking knobs in your compiler, or use a tool such as valgrind.

In your array initialization code you allocate 'tokens[i].size()' characters for each 'tokens[i]' element, and then you initialize elements from 0 to 'tokens[i].size()'. This is obvious memory overrun. If you want to have elements from 0 to 'tokens[i].size()', you need to allocate an array of size 'tokens[i].size() + 1'.

Your description sounds correct, but the code you've posted is incomplete. In particular if you only call

my_array[i] = new char[M];

for some elements of the array (not all N), then you'll have garbage in the other elements, which will cause the heap corruption detected in the delete loop you see.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM