Concepts / Pointers and Memory Addresses in C++

Pointers and Memory Addresses in C++

Check every void* assignment when porting C code to C++. If the code relies on an implicit conversion to another pointer type, C++ rejects it; make the conversion explicit and review whether the target type is appropriate.

  • Programming

One Assignment, Two Language Rules

A pointer assignment that looks ordinary in C can stop compiling when the same code is moved to C++. The key difference is how the languages handle converting a generic void* to a pointer with a specific type. Before looking at the rule, predict what happens in C++ when a void* that points to a character is assigned to an int* without a cast.

What do you think happens?

In C++, is this assignment accepted without a cast: int* p = void_ptr; when void_ptr has type void*?

  • Yes, because void* can point to any object type.

  • No, because C++ does not allow this implicit conversion.

Reveal answer
Answer:

No. In C++, assigning a void* to an int* requires an explicit conversion.

The fact that void* can point to an object of any type does not mean C++ implicitly converts it to every other pointer type.

void* to int*Acceptedvoid* to int*Rejectedimplicit conversion allowedimplicit conversion not allowed
Why does an assignment from void* to int* pass in C but fail in C++?

Check the Conversion Before the Assignment

A void* is a generic pointer: it can point to an object of any type, but it does not carry information about the type of the object it points to. C permits a void* to be assigned to a pointer of another type without a cast. C++ does not permit that implicit conversion. So, when you encounter an assignment from void* in C++, first check whether the assignment includes an explicit conversion. If it does not, the assignment is rejected under this rule.

Pointer assignmentSource is void*Explicit cast presentImplicit conversionrejectedNot this conversionConversion isexplicityesnonoyes
What checks decide whether a void* assignment is accepted under the implicit-conversion rule?
Worked example

Predict the C++ Result

A character variable is pointed to by a void*. An int* is then assigned from that void* with no cast. Is the assignment accepted in C++?

  1. 1
    Identify the source type

    The value being assigned has type void*.

  2. 2
    Identify the target type

    The destination has type int*.

  3. 3
    Apply the C++ rule

    The assignment asks C++ to convert void* to another pointer type implicitly, which is not allowed.

Result

The assignment is rejected in C++. Adding an explicit conversion makes the conversion visible in the code; it does not by itself establish that the pointed-to memory is safe to use as an int.

When a Pointer Writes Past Its Object

Making a void* point at an object does not make the memory large enough for every other type. If that address is treated as a pointer to a larger type, a write through the converted pointer can reach bytes beyond the original object. For example, the source describes a character object and an int* assigned from the void* that points to it. A write through that int* can overwrite the character and nearby bytes that belong to something else. The available facts establish this possible overrun, but do not specify an exact number of bytes for it.

Character objectchLarger-type writeCan reach beyond chNearby bytesOther storagewrites at its addressmay overwrite
What can happen when a pointer to a larger type is used to write at the address of a character object?

Handle malloc() Results Explicitly

malloc() returns a void* pointing to allocated memory. C allows that result to be assigned to a pointer of another type without a cast; C++ does not. When using malloc() in C++, cast its result to the intended pointer type. The source's practical guidance is to avoid malloc() in C++-only code. When moving C code into a C++ project, look for implicit void* conversions and make each conversion explicit so the intended target type is visible.

malloc() returnsvoid*Assign to typedpointerNo cast requiredmalloc() returnsvoid*Cast to target typeC++-only codeAvoid malloc()required for typed assignmentsource guidance
How does the pointer returned by malloc() need to be handled in each language?
SituationCC++
Assign void* to another pointer typeImplicit assignment is allowed.An explicit conversion is required.
Assign malloc() result to a typed pointerNo cast is required for the assignment.Cast the result to the intended pointer type.
C++-only codeNot applicable.The source advises avoiding malloc().

The language difference concerns the conversion from void* to a typed pointer.

Practice the Porting Check

EASY

A C file contains an assignment from a void* variable to a pointer of another type, with no cast. You are reviewing it for use in a C++ project. What does the C++ compiler do with that assignment, and what change does the source recommend?

Hints
  • Identify the source and destination pointer types.
  • Apply the C++ rule for implicit conversion from void*.
  • Consider what should be made explicit when porting the code.
Key point

Check every void* assignment when porting C code to C++. If the code relies on an implicit conversion to another pointer type, C++ rejects it; make the conversion explicit and review whether the target type is appropriate.

Key Takeaways

  • C allows void* to be assigned to another pointer type without a cast; C++ does not allow that implicit conversion.
  • In C++, an assignment from void* to a different pointer type needs an explicit conversion.
  • Treating memory for a smaller object as a larger type can make a write reach nearby bytes; the exact overwrite extent is not specified here.
  • In C++, cast a malloc() result to the intended pointer type, and avoid malloc() in C++-only code as the source advises.
  • When porting C code to C++, search for implicit void* conversions and review each target type.

More concepts starting with P