Home > Enterprise >  Malloc always returns a NULL pointer; Visual Studio 2022
Malloc always returns a NULL pointer; Visual Studio 2022

Time:03-02

This may be a duplicate question but I checked out other question like this and never really found what I was looking for (or so i believe).

Consider the following code:

#include <iostream>
#include <stdlib.h>

int main()
{   
    char* s = (char*)malloc(2 * sizeof(char));

    *s = 'M';

    s  ;

    *s = 'I';

    std::cout << s[-1] << s[0] << s[1];
}

Output:

MI²

My problem is that, whenever I try to use malloc/calloc/realloc I always have the same error message pop up that says that s (cf. code above) is an 'unreferenced NULL-pointer'.

I really don't see the problem here. Especially because both 'M' and 'I' have been allocated to the array I initialized via malloc, but they're in odd places. I'd expect: s[0] = 'M' and s[1] = 'I' but instead it's s[-1] = 'M' and s[0] = 'I', which I find rather strange.

Where did I go wrong?

CodePudding user response:

To be clear, that message is a warning by the compiler, its not that you are getting null from malloc, it warns that you might and have not checked

https://docs.microsoft.com/en-us/cpp/code-quality/c6011?view=msvc-170

The message goes away if you do

char* s = (char*)malloc(2 * sizeof(char));
if (s != NULL)
{
    *s = 'M';

    s  ;

    *s = 'I';

    std::cout << s[-1] << s[0] << s[1];
}

There is another warning though

https://docs.microsoft.com/en-us/cpp/code-quality/c6200?view=msvc-170

This is warning that s[-1] looks very odd. Its ignoring the fact that you did s earlier which makes this ok.

Whats not ok is

 std::cout << s[-1] << s[0] << s[1];
 ------------------------------*****

this is accessing data beyond the end of the allocation, result is Undefined Behavior.

if you do

int main()
{
    char* s = (char*)malloc(2 * sizeof(char));
    if (s != NULL)
    {
        s[0] = 'M';

        

        s[1] = 'I';

        std::cout << s[0] << s[1] << s[2];
    }
}

which is a much more straightforward way of doing the same thing then VS will warn you about that s[2] being out of bounds

CodePudding user response:

You shouldn't have changed s in the line s ;
s points to the base of your allocation. So when you increment it, it's natural that s[0] points to 'I'.

If you want to assign the 2nd position of your memory allocation, or the ith for that matter, you can either use this s[i] = 'M';, or you can do this: *(s i) = 'M';.\

But the former is the better practice, since it's more readable. I believe most people would pause upon facing the latter, as it's quite rare to see these days.

Additional Info

In fact, when you use s[i] = 'M';, the compiler just translates it to *(s i) = 'M';. So this [] is just an operator that is defined on the pointer type, and it simply adds its argument, which is named i in most cases, to the base of the pointer.

  • Related