2016-11-25 3 views
1

Я пытаюсь изменить размер массив символов, я следовал: Resizing a char[] at run timeДинамическая память изменения размера массив символов

затем:

я сделал что-то вроде этого:

// this crashes in runtime: 

const long SIZE_X = 1048576; 

char* Buffsz = new char(sizeof(char)); 

for(int i = 0; i < (SIZE_X - 2); i++) 
{ 
    Buffsz[i] = 'a'; 
    if(realloc(Buffsz, sizeof(char) * i) == NULL) // autoallocate memory 
     cout << "Failled to reallocate memory!" << endl; 
} 

но если я это сделаю:

// this works without problems. 
const long SIZE_X = 1048576; 

char* ABuffsz = new char[SIZE_X]; 

for(int i = 0; i < (SIZE_X - 2); i++) 
{ 
    ABuffsz[i] = 'a'; 
} 

cout << "End success! len: " << strlen(ABuffsz) << endl; 

Для меня это должно быть хорошо, но если это неправильно, w i может автоматически выделять память?

P.S: Я знаю об использовании std::vector, но я хочу использовать это, если возможно.

+0

Это простой пример, 'SIZE_X', это просто предел для первого примера. – nikomaster

+1

realloc выделяет * новый * блок. Но в вашем коде Buffsz продолжает указывать на старый блок, который только что был освобожден. Кроме того, ваш код выделяет один символ, записывает в первый элемент, перераспределяет его на * zero * chars, записывает во второй элемент (который не существует), перераспределяется на один символ, записывается в третий элемент (который не есть), ... – immibis

ответ

1

realloc() предназначен для изменения размера массивов С-стиля, которые были выделены с помощью malloc(). realloc() не может использоваться в коде C++, чтобы изменить размер объектов C++, созданных в динамической области с помощью new.

В C++ нет эквивалента для realloc(). В C++ самый простой способ изменить размер существующего массива: новый массив должен быть сконструирован в динамической области с new [], значения из существующего массива std::copy -ed для нового массива, а затем старый массив delete[] -ed.

Это очень много работы. Это потребует много ненужных построений по умолчанию и присваивания копий (и если у ваших классов нет конструкторов по умолчанию, вы застряли). Используя конструкторы компоновки - new и manual copy/move, можно оптимизировать некоторые из этих работ. Но это большая работа. Вот почему вы должны использовать std::vector. Он делает все это для вас, и он делает это правильно.

Нет ничего плохого в использовании new и delete самостоятельно, как вы хотели бы это сделать. Это хороший опыт обучения, чтобы получить некоторое представление о том, как правильно управлять объектами с динамическим охватом. Полное понимание того, как работают низкоуровневые динамические исследования, - это ценные знания. Однако в какой-то момент все это становится реальным старым, а нетривиальные задачи, связанные с объектами с динамическим охватом, становятся утомительными и подверженными ошибкам, а также являются основными источниками времени.

В этот момент единственный способ сохранить то, что осталось от здравомыслия, - начать использовать контейнеры библиотек C++, которые позаботятся о всех гранжевых работах для вас. В заключение: используйте std::vector, и пусть это сделает все это для вас.

+0

Я не знал об этом, я думал, что это возможно, у меня нет выбора, кроме как использовать 'std :: vector'. большое спасибо. – nikomaster

1

Для использования realloc памяти должно быть выделено malloc или другая функция в этом семействе.

Простейший способ справиться со строками char в C++ - использовать std::string.

0

Вы не можете использовать realloc() на указателе выделенной памяти оператором new.Вы можете использовать эту функцию, чтобы изменить размер указатель

char* Resize(char*& old,long int length,long int resize_to) 
{ 
    char* new_ptr; 
    new_ptr = new char[ resize_to ]; 
    long int least = (length < resize_to) ? length : resize_to; 
    for(long int i = 0;i < least ; ++i) 
     new_ptr [i] = old[i]; 
    delete [] old; 
    old = nullptr; 
    return new_ptr; 
} 

Это может сработать, и не забудьте, что delete[] не перераспределяются указатель после того, как он больше не нужен, или вам придется беспокоиться о памяти утечка

Хотя вы можете захотеть нас std::string или std::vector или создать свой динамически расширяющийся класс стека.

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