std::vector for pods I am learning c++ and read why we can't use realloc() in std::vector, but i think we can use realloc() for pods, so here is my attempt to write std::vector like class template specialized for PODs

#include &lt;malloc.h&gt;
#include &lt;stdexcept&gt;
#include &lt;type_traits&gt;

namespace gupta {
namespace detail {
namespace podvector {
template &lt;typename T&gt; inline auto malloc(size_t elm_count) {
  return ::malloc(elm_count * sizeof(T));
}

template &lt;typename T&gt; inline auto realloc(void *old_block, size_t elm_count) {
  return ::realloc(old_block, elm_count * sizeof(T));
}
} // namespace podvector
} // namespace detail

template &lt;typename PodType,
          typename = std::enable_if_t&lt;std::is_pod&lt;PodType&gt;::value&gt;&gt;
class podvector {
public:
  using value_type = PodType;
  using size_type = size_t;
  using pointer = value_type *;
  using const_value_pointer = const value_type *;

  ~podvector() {
    if (m_memory)
      free(m_memory);
  }

  podvector(size_type initial_size = 0) {
    alloc(initial_size);
    m_size = initial_size;
  }

  podvector(size_type initial_size, const value_type &amp;value)
      : podvector(initial_size) {
    for (auto &amp;v : *this)
      v = value;
  }

  podvector(const podvector &amp;other) : podvector(other.m_size) {
    for (size_type i = 0; i &lt; m_size; i++)
      m_memory[i] = other.m_memory[i];
  }

  podvector(const podvector &amp;&amp;other)
      : m_memory{std::move(other.m_memory)},
        m_capacity{std::move(other.m_capacity)}, m_size{
                                                     std::move(other.m_size)} {
    // other.m_memory = nullptr;
    other.alloc(0);
  }

  podvector &amp;operator=(const podvector &amp;rhs) {
    if (this != &amp;rhs) {
      resize(rhs.m_size);
      for (size_type i = 0; i &lt; rhs.m_size; i++)
        m_memory[i] = rhs[i];
    }
    return *this;
  }

  podvector &amp;operator=(podvector &amp;&amp;rhs) {
    if (this != &amp;rhs) {
      this-&gt;~podvector();
      m_memory = std::move(rhs.m_memory);
      m_capacity = std::move(rhs.m_capacity);
      m_size = std::move(rhs.m_size);
      // rhs.m_memory = nullptr;
      rhs.alloc(0);
    }
    return *this;
  }

  void resize(size_type new_size) {
    if (new_size &gt; m_size)
      change_capacity(new_size);
    m_size = new_size;
  }

  void reserve(size_type new_capacity) {
    if (m_capacity &lt; new_capacity)
      change_capacity(new_capacity);
  }

  void push_back(const value_type &amp;new_elm) {
    if (m_size + 1 &gt; m_capacity)
      change_capacity(std::min(m_capacity * 2, 1));
    m_memory[m_size++] = new_elm;
  }

  void pop_back() { m_size--; }

  auto size() const { return m_size; }
  auto capacity() const { return m_capacity; }
  pointer begin() { return m_memory; }
  const_value_pointer begin() const { return m_memory; }
  pointer end() { return m_memory + m_size; }
  const_value_pointer end() const { return m_memory + m_size; }
  value_type &amp;operator[](size_type pos) { return m_memory[pos]; }
  const value_type &amp;operator[](size_type pos) const { return m_memory[pos]; }

private:
  pointer m_memory;
  size_type m_size, m_capacity;
  void alloc(size_type capacity) {
    m_capacity = capacity;
    m_size = 0;
    m_memory =
        static_cast&lt;pointer&gt;(detail::podvector::malloc&lt;value_type&gt;(capacity));
    if (!m_memory)
      throw std::bad_alloc{};
  }
  void change_capacity(size_type new_capacity) {
    m_capacity = new_capacity;
    void *new_memory =
        detail::podvector::realloc&lt;value_type&gt;(m_memory, new_capacity);
    if (!new_memory)
      throw std::bad_alloc{};
    m_memory = static_cast&lt;pointer&gt;(new_memory);
  }
};

} // namespace gupta
malloc and realloc live in cstdlib. malloc.h is not a standard header, neither in C++ nor in C, and should not be relied on in any case. 
Also, you're missing #include &lt;utility&gt; for std::move.
Legacy C functionality, as everything else from the standard library, lives in the std namespace, if you include the corresponding &lt;cheader&gt; files. While you can also include the C standard headers via &lt;header.h&gt;, this is highly discouraged. With the first option, names may also exist in the global namespace, but this is not guaranteed and should not be relied on.
Your malloc and realloc functions need not be inline. In fact, inline does nothing here; remove it.
You don't need to check for null pointers when freeing memory. Passing a null pointer to free is always well defined and does nothing.
You don't need to move out all the data members from other in your move constructor. All of those members are trivial to copy, and have no special move behavior.
The move assignment operator invokes undefined behavior. You cannot just call the destructor of an object and then write to its members. Calling the destructor completely ends the lifetime of the object; afterwards, there's nothing there to write to. Furthermore, this is a kind of anti-pattern; in almost all cases, the move assignment operator should be implemented via the copy-and-swap idiom.
push_back is broken. You call change_capacity with the result of std::min(m_capacity * 2, 1), which is either 0 or 1, in any case. Most likely, you'd want to use std::max instead.
if (m_size + 1 &gt; m_capacity) looks strange to my eyes. I would just write if (m_size &gt;= m_capacity).
pop_back should definitely return a value. It's not very useful otherwise. 
Since you're going for what seems to be a std-like container interface, you should add a little more functionality. For one, you're missing some of the usual type definitions, such as iterator and const_iterator. Furthermore, some sort of emplace mechanism would be appropriate, as well as some way to clear the container and some functionality to shrink it, as well as some other things.
You should make sure that memory is properly initialized. As a user, I would expect that it's safe to access every element in bounds; however, you are not initializing memory at all, leaving that job to the user. I'd expect memory to be default- or zero-initialized; making use of std::calloc should do the trick (alternatively, you can also just std::memset the area). 
I would make your malloc and realloc functions a little bit more useful. As of right now, the onus of checking whether allocation succeeded is put on the user of those functions, but in my opinion it would be much cleaner and safer to lift those functions to a "C++-safe" level, i.e. make them check the return value of the underlying allocation call directly and convert that into an exception directly.
std::is_pod is being deprecated, in accordance with the standard library moving away from the term POD as a whole. Also, the requirement that T must be a POD type is too strict; your vector will still work correctly if T is trivial.