What is "Expression must have class type"

Viewed 826

I used std::malloc() on a pointer which is a member of an object. And in a method, it threw an error.

[...]
class SomeClass
{
  public:
    void method()
    {
      this.ptr = std::malloc(4);
    }

    int* ptr;
}
[...]

And it throws an error saying:

Error: Expression must have class type

What is the problem in my program?

5 Answers

It's probably because this is a pointer and to try to access it using .. Moreover malloc returns a void* so you must cast

Try writing this instead :

this->ptr = static_cast<int *>(std::malloc(4));

You have at least two problems:

First, it should be this->ptr instead of the dot.

Second, you must cast the result of malloc() to the pointer type you want. For example, this->ptr = static_cast<int *>(malloc(4));

There are some other problems with your code too.

  1. You must free() the pointer you've allocated. If you malloc it, you'd have to free it somewhere too.

  2. You are assuming that an int is four bytes in size. This is not correct. You should use sizeof(int). Or at least add a static_assert(sizeof(int) == 4); if you have to assume it.

  3. If you use new to allocate memory (instead of malloc) like this: this->ptr = new int;, you simultaneously get rid of two of the problems above. You won't need to cast the returned pointer, and you won't assume the size of an int to always be 4.

  4. If you use new, don't forget to delete the pointer (instead of free.)

  5. Always initialize your pointers to nullptr, and remember to set them to nullptr after freeing/deleting them too. This helps you avoid some common silent bugs.

Stylistically, you can avoid using a raw pointer and instead use something like a std::unique_ptr<int>. But that's up to you.

C++ is not Java. You need this-> rather than this..

Although in your case you can write, simply, ptr = (int*)std::malloc(4) since the this-> is implicit.

Better still, write ptr = new int; because then you're not making assumptions about sizeof(int). Don't forget you need a delete int; somewhere too and you need to worry about assignment operators, copy constructors, and the destructor.

Even better then to use std::unique_ptr<int> or std::shared_ptr<int> for the ptr type, so you don't need to worry about the delete.

Even better perhaps, use int as the member type, if the requirements allow.

this.ptr is not valid!

this is a pointer and the members must be accessed with the pointer operator:

this->ptr = static_cast<int *>(std::malloc(4));

What strange compiler gives error message like this?

It complains about left side of dot operator in this.ptr expression. Dot operator assumes that left side should be a class-type, while this is a pointer to a class-type. You have to use ->.

Secondly, malloc returns void*, you have to convert it. Avoid the hassle and use new int unless you really must to use malloc.

Related