мой узел содержит int и строковую переменную, и я попытался использовать двоичное дерево поиска. код выглядит следующим образом:
struct node{
int a;
string members[5];
};
int main(){
node * root = NULL;
root = (node*)malloc(sizeof(node));
root->members[0] = "aaaaa";
return 0;
}
конечно, мой код был не совсем таким, я сделал это кратко, потому что я хочу показать только проблему. он дал мне "место записи нарушения прав доступа". Я попытался использовать 'new node();' вместо malloc, и этого не произошло. почему это точно?
malloc()
выделяет только память. Он не вызывает конструктор объекта. Вы можете вызвать конструктор в выделенной памяти, например,
void* mem = malloc(sizeof(node));
if (mem) {
node* root = new(mem) node;
// ...
}
При использовании new node
вместо malloc(sizeof(node)
выделенная память также инициализируется. Использование неинициализированного объекта - неопределенное поведение.
malloc
выделяет только исходное хранилище. new
выделяет необработанное хранилище и инициализирует его, чтобы он содержал указанный тип.
Если вы выделяете только типы POD, это различие в основном относится к формулировке, с небольшим количеством реальных различий в том, что происходит.
Если вы выделяете что-то вроде std::string
, у которого есть конструктор, есть мир различий. Если вы используете new
, то ваши string
переменные все были инициализированы, чтобы они были реальными (хотя и все еще пустыми) строками. Когда вы просто используете malloc
, они не были инициализированы вообще - они просто куски неинициализированного необработанного хранилища нужного размера, чтобы содержать string
. Когда вы пытаетесь использовать их как строку, быстрый крах - это лучшее, на что вы можете надеяться.
new
. Для определенных типов (POD) он также работает просто для выделения памяти, но нет ничего плохого в том, чтобыnew
объекты были такими, и на самом деле это проще, чем использоватьmalloc()
.