2015-05-30 3 views
0

Раскрытие информации: Я пытаюсь решить проблему со строгими ограничениями времени и памяти. Обычно я использую векторы и строки, но здесь мне нужно самое быстрое и наименьшее решение (с векторами, которые на самом деле выполнялись над пределом времени), поэтому я обратился к динамическим массивам char *. Соответствующие части моего кода:Удаление динамического символа ** в C++

char** substrings(string s, int* n){ 
    *n = 0; 
    ... 
    //////////////////////////////// 
    char** strings = new char*[*n]; 
    //////////////////////////////// 
    for (int i = 0; i < s.length(); i++){ 
     for (int j = 1; j < s.length() - i + 1; j++){ 
      ... 
      strings[si] = tmp; 
      ... 
     } 
    } 
    return strings; 
} 

int main(){ 
    ... 
    for (int ti = 0; ti < t; ti++){ 
     cin >> s; 
     char** substr = substrings(s, &n); 
     ... 

     for (int i = 0; i < n; i++){ 
      delete substr[i]; 
     } 
    } 
    return 0; 
} 

Все работает просто отлично без удаления массива (массивов), но это неприемлемо, так как я иду по этому поводу? Я пробовал много вариантов, которые казались логичными, но я получаю ошибки времени выполнения.

+0

Я считаю, что низкая производительность связана с вашим алгоритмом, а не с использованием 'std :: string' или' std :: vector'. – 101010

+0

вы не можете сделать это быстрее, чем вектор, потому что вектор использует ту же «новую», просто предопределяющую векторную память, указав количество элементов. –

+0

Фактически использование символов вместо строк помогло мне приблизиться к сроку с несколькими сотыми долями секунды. Проблема с векторами, я думаю, заключалась в том, что тестовые примеры добавляли элементы много тысяч раз, и перераспределение занимало слишком много времени. Я хотел сэкономить время, выделив память только один раз, и именно поэтому я использовал массив. – b4kancs

ответ

7

Это похоже на распределение, но в обратном порядке, и используя delete[] вместо new[]:

for(int i = 0; i < LENGTH; i++) 
    delete[] strings[i]; // delete each pointer in char** strings 
delete[] strings; // finally delete the array of pointers 

Я предположил, что здесь LENGTH длина массива указателей на char*. Так это выглядит, что вы только выполнить первый раунд де-распределения

for (int i = 0; i < n; i++){ 
     delete substr[i]; // need delete[] substr[i] here 

но с delete вместо delete[], вам нужно delete[] substr[i] вместо этого, поскольку я думаю, что substr[i] является char* указатель, указывающий на первый элемент массива от char s размещено на new[]. Вы, наконец, нуждаетесь в дополнительном

delete[] substr; 
+0

Привет, я действительно пробовал это раньше, но у меня все еще появляется ошибка «HEAP CORRUPTION DETECTED». Кроме того, не удаляет [] для удаления объектов, вызывая их деструкторы? Вот мой полный код, возможно, это поможет: http://pasted.co/39f75c26 – b4kancs

+0

@ b4kancs no, 'delete []' ** always ** пытается освободить память для динамически выделенного массива. Если массив состоит из объектов, то каждый объект в массиве будет иметь вызванный деструктор. В вашем случае ваши элементы массива являются указателями 'char *', которые не имеют деструкторов, и поэтому вам нужно добавить дополнительный 'delete [] substr [i]' в первый цикл. Попробуйте код, который я предложил, и если он не работает, убедитесь, что ваши «новые» распределения правильные, т. Е. Убедитесь, что вы выделяете достаточно места для каждой подстроки (не забудьте, возможно, о '' \ 0'' string terminator). – vsoftco

+0

Вы были правы, проблема заключалась в том, что у моих строк не было завершающего байта «0» в конце, поэтому я предполагаю, что программа пыталась получить доступ к «неправильной» памяти. Интересно, что он по-прежнему не работает должным образом, по крайней мере, я получаю на сотни мегабайт больше использования памяти, чем раньше (с векторами он работал с ~ 64000 КБ, теперь он использует более ~ 350000). – b4kancs

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