2009-10-12 2 views
3

Я создал 2d массив с-строк с помощью:удаление символа ** правильно?

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

, а затем я инициализируется каждую строку с помощью:

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

Так что я очень много получил зубчатую 2d массив.

Я хотел продолжить и удалить все это так:

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

заканчивающуюся на:

delete [] my_array; 

для цикла дал мне НЕАР КОРРУПЦИЕЙ ERROR - почему?

************** ОБНОВЛЕНИЕ - полный код *********************

#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; 
} 

Если у вас не установлен boost: конвертируйте BOOST_AUTO_TEST_CASE в main() и voil'a.

Что выше вещь делает: преобразует вектор в гольца **

+2

Я не знаю ответа, но почему бы вам просто не использовать вложенный std :: vector ? –

+1

Возможно, вы имели в виду 'std :: vector '. – avakar

+0

nah, если бы я хотел использовать вектор , это было бы торт – Maciek

ответ

3

В коде инициализации массива вы выделяете символы tokens [i] .size() для каждого элемента tokens [i] ', а затем вы инициализируете элементы от 0 до' tokens [i] .size() ' , Это очевидное переполнение памяти. Если вы хотите, чтобы элементы от 0 до 'tokens [i] .size()', вам нужно выделить массив размерных токенов [i] .size() + 1 '.

+0

Боже, я только что заметил это. БЛАГОДАРЯ ТОННУ. – Maciek

6

Ваш код представляется правильным. Скорее всего, ваше повреждение кучи вызвано каким-то другим кодом и обнаруживается только при запуске этого кода освобождения.

Вы можете проверить это, выполнив указанный выше код отдельно, без какого-либо другого кода. Вы должны быть в состоянии проверить, что от этого нет кучи.

В зависимости от вашей среды разработки, включите все ручки проверки распределения памяти в своем компиляторе или используйте такой инструмент, как valgrind.

+1

уже есть, я использую фреймворк boost/test/unit_test.hpp, в модульных тестах есть довольно хорошая сборка mem-leak. Если я пропущу зацикленное удаление [], я получаю утечку mem, поскольку отдельные строки не выделяются. если я его добавлю - WHAM - ошибка повреждения кучи – Maciek

+0

Похоже, вы на правильном пути с инструментами. Однако обнаружение утечки памяти не будет обнаруживать запись за конец выделенного массива. Например, поскольку вы выделяете 'my_array' с N элементами, убедитесь, что вы ничего не храните в' my_array [N] '. Если да, то будет конец конца выделенного массива. –

2

Ваше описание звучит корректно, но код, который вы опубликовали, является неполным. В частности, если вы только звоните

my_array[i] = new char[M]; 

для некоторых элементов массива (не все N), то вы будете иметь мусор в других элементах, которые вызовут повреждение кучи обнаруженное в цикле удаления вы видите.

Смежные вопросы