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.