Need help in understanding malloc(0) for my example [duplicate]
Asked Answered
O

4

6

I am trying to understand inners of double pointer (which is pointer holding another pointer) to form an array of pointers. So, I am trying to run the following code by experimenting on malloc to debugging and see how it works. I am unable to understand what malloc(0) does in my case, but my code works by outputting "Hello World".

What is the diff between

pToCharsPointers = (char**) malloc(0);

and

pToCharsPointers = (char**) malloc(2 * sizeof(char*));

Please someone clarify what it is doing in my case.

#include <stdio.h>

char **pToCharsPointers;

int main(void)
{
    pToCharsPointers = (char**) malloc(0);

    char* pToChars = "Hello";
    *pToCharsPointers = pToChars;

    *(pToCharsPointers + 1)= "World";

    printf("%s %s\n", *(pToCharsPointers + 0), *(pToCharsPointers + 1));

    return 0;
}

Also, I would really appreciate if you anyone could explain how double pointers works with an example in memory for visualizing as I fail to see myself even though I tried to read about this in many places.

EDIT: Thanks everyone for sharing your answers, and it really helped to understand. I got a valid pointer with malloc(0) when I printed it, and can dereference it also without issues during multiple tries. Wanted to understand why its working. Seems like in my case undefined behavior was actually a expected one.

Overplus answered 24/2, 2017 at 9:4 Comment(1)
On an unrelated note, *pToCharsPointers is equal to pToCharsPointers[0], and *(pToCharsPointers + 1) is equal to pToCharsPointers[1].Tighten
B
6

In your code

(char**) malloc(0);

is wrong for two reasons, like

Any code, attempting to use the returned pointer for a code like yours, will be essentially dereferencing invalid memory which invokes undefined behavior. So, the output/behaviour of your program can neither be predicted nor reasonified.

OTOH, a statement like

pToCharsPointers = malloc(2 * sizeof(char*));

is valid but you ought to check the validity of the returned pointer to ensure malloc() is success.

Bondman answered 24/2, 2017 at 9:6 Comment(8)
But my code works as expected which is why I asked this question. Can you tell me why please ?Overplus
@DineshG Seemingly working okay is one of the possibilities of undefined behavior.Tighten
@DineshG Probably because your implementation doesn't return NULL, but some other value. You could print it. But all of doesn't matter, it's undefined behavior anyway.Secco
Just to avoid any possible confusion, what @Secco meant is, printing the returned pointer is OK, dereferencing that is not.Bondman
Dear @**downvoter**, if you care to leave a comment along with the downvote it'll help me understanding the mistake and improve the post for better. Thank you.Bondman
@SouravGhosh The reason is your usual claim, that casting the return value is wrong.Crosslink
@Crosslink Thanks, much appreciated. Sorry, but I stand by my statement. :)Bondman
@SouravGhosh No need to be sorry, freedom of speech is very precious ;)Crosslink
S
3

I will try to explain:

pToCharsPointers = (char**) malloc(0);

this line will bring to pToCharPointers a pointer that you can't use

but you can't know if an error will come. don't do that!

char* pToChars = "Hello";
*pToCharsPointers = pToChars;

this line will bring *pToCharsPointers to pToChar that pointing to the "Hello".

*(pToCharsPointers + 1)= "World";

this line will write in *(pToCharsPointers + 1), that you can't know to where it is pointing, "World". also, an option to an error but not for sure.

printf("%s %s\n", *(pToCharsPointers + 0), *(pToCharsPointers + 1));

this line will print "Hello Wolrd" if you didn't get any errors yet.

Sideburns answered 24/2, 2017 at 9:28 Comment(0)
T
2

It simply asks to allocate zero bytes. It is up to the implementation of malloc if it should return a null pointer or not.

Even if it returns a non-null pointer, you can't dereference it since it will automatically be out of bounds. Dereferencing the returned pointer will lead to undefined behavior in both cases.

When you do malloc(2 * sizeof(char*)) you allocate enough space for two pointers to char.

Tighten answered 24/2, 2017 at 9:7 Comment(0)
O
2

You forgot to include <stdlib.h>. Calling malloc() without a proper definition has undefined behavior. Explicitly casting its return value hides the fact that the compiler may assume it returns an int value. This cast is necessary in C++, where calling a function without a prior definition is invalid, but it is counter-productive in C.

Regarding your question: allocating a block of size zero can have two possible outcomes, depending on the implementation of your C library:

  • malloc(0) can return NULL, and attempting to store values at this address has undefined behavior.
  • malloc(0) can return a valid non-null pointer, but this pointer cannot be dereferenced, nor used to store anything as the size of the object it points to is 0.

In both cases, your code has undefined behavior, which may or may not be a crash.

Oliy answered 24/2, 2017 at 9:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.