0

I want to employ a queue as a member of struct, but the following code goes wrong when run it.

#include "stdafx.h"
#include <math.h>
#include <stdio.h>
#include <queue>

typedef struct {
    int a;
    std::queue <int> b;
}Qtest;

int main(void)
{   
    char *WorkingBuffer = NULL;
    WorkingBuffer = (char *)malloc(sizeof(Qtest));
    Qtest *st = (Qtest *)WorkingBuffer;
    std::queue<int> c;
    c.push(1);
    st->a = 0;
    st->b.push(1);
    return 0;
}

However, if I define a queue out of the struct, it can work. I have no idea about this, can anyone give me some advice?

Ryuk
  • 19
  • 3
  • 3
    A `std::queue` has a constructor which has to be executed after allocation. With your hack `WorkingBuffer = (char *)malloc(sizeof(Qtest)); Qtest *st = (Qtest *)WorkingBuffer;`, this is not done. This is a clear case of [U.B.](https://en.cppreference.com/w/cpp/language/ub). Why not `new`? (It was invented for a reason.) At least, you could perform a [placement new](https://stackoverflow.com/a/222578/7478597) but I'm not sure whether this can cure the U.B. completely. (Alignment?) – Scheff's Cat Dec 29 '20 at 08:56
  • @Scheff Thanks for your explaination, it works when I use new to create the struct. – Ryuk Dec 29 '20 at 09:40
  • `new` may call `malloc()` "under the hood" (or may not). However, using `malloc()` in C++ is usually very wrong. (You just learnt in practice why.) Meanwhile, much effort has been done to make the usage of `new` in C++ unnecessary as well. The C++ standard library provides a lot of safer wrappers to write serious software without any literal `new` in code. You can use [containers](https://en.cppreference.com/w/cpp/container) instead or [smart pointers](https://en.cppreference.com/w/cpp/memory) or even [std::optional](https://en.cppreference.com/w/cpp/utility/optional) as possible replacements. – Scheff's Cat Dec 29 '20 at 09:46

1 Answers1

1

This is the difference between malloc/free and new/delete. malloc only allocates memory without calling the constructor. Meanwhile, the new operator allocates memory and and calls the constructor. This is almost always what you want in C++ and so you should only use malloc in very low-level code.

Joel Croteau
  • 1,682
  • 12
  • 17
potter lv
  • 11
  • 1