2

From this question, I understand why the code below may not work:

int *ptr;
*ptr = 1000;
printf("%d", *ptr);

when I compiled and run it using: gcc file.c; ./a.out I got:

Segmentation fault (core dumped) ./a.out

ptr here may point to a random location without an initialized variable. Is that correct?

However, when using malloc() that issue does not occur.

int *ptr = malloc(sizeof(int));
*ptr = 1000;
printf("%d", *ptr);

Does malloc initialize the variable that its pointer is pointing to?

4
  • malloc() doesn't initialize the variable, but it reserves some space (size that you require) in memory, usually you require the the space needed by the size of the variable based on its type. Commented Dec 8, 2020 at 6:55
  • 1
    Is that a typo? int *ptr = 1000; Should that be *ptr = 1000; as in first code? Commented Dec 8, 2020 at 6:55
  • 1
    What do you mean with "withour variable initialization"? Assigning a value during definition of a variable is exactly an initialization. It does not matther where you get that value. Commented Dec 8, 2020 at 6:58
  • I was wondering why int *ptr; *ptr = 1000 returns segmentation fault upon printing. When I used malloc, this did not occur and I was able to print the value ptr is pointing to. Commented Dec 8, 2020 at 7:07

3 Answers 3

2

Short answer: No

malloc does not initialize the variable. It just allocate the memory. You can put integer into the function, for example malloc(8), it will just allocate 8 bytes for later use. If you look further into the malloc function, it actually returns void* datatype. It can be later typecasted into other datatype.

From your code malloc(sizeof(int)), actually sizeof(int) returns an integer for the size of the datatype/variable you put into it.

Sign up to request clarification or add additional context in comments.

3 Comments

If I use int *ptr = malloc(4); I do not get segmentation default error from the second code block. The first code block that uses int *ptr; however returns segmentation fault when I try to print
@Shahin on your first code block, you do not allocate the memory needed. That's why you can't assign any value into it.
I think I understand it now. when I use int *ptr;. memory is allocated using malloc() for dynamic allocation or initialize an int variable for the pointer for static allocation (int num; int *ptr = &num). arrays also allocate memory: int ptr[sizeof(int)]
1

The post you linked explains it more or less. One thing is doesn't touch on is undefined behavior - which is exactly what will happen in your version without malloc.

All sorts of things can go wrong if you try to use such a pointer - you haven't said where it should point to. It could point literally anywhere.

This line:

int *ptr = malloc(sizeof(int));

is indeed an initialization. What's happening here is two things: (1) malloc is reserving space in memory so that you can subsequently use the pointer and (2) its returning the starting address of that memory.

The address gets assigned to ptr - which is itself a variable. And, like all variables, you can't use them uninitialized. If you do, that's invalid code and therefore, it results in undefined behavior.

Let's drill down this point a little more:

If you don't call malloc, your pointer is invalid and should not be used. To prove this, try compiling your code, say using good old gcc.

If you run:

gcc program.c  # no flags

it will compile -- but just because gcc gave you a binary, it doesn't mean it will do what you want. When you run it, it will (most of the time) fail miserably.

However, if you run:

gcc -Wall program.c  # enable warnings

it will warn you that ptr is being unused uninitialized. But, it will still produce a binary which you can run - resulting in the same thing as before.

Finally, if you run:

gcc -Wall -Werror program.c  # enable warnings and turn them into errors

it will again warn you of the same thing but this time, it won't produce a binary -- and this is what you really want in this situation. Here, gcc is telling you that something is really very wrong and that your code is simply not valid.

Now, back to the point about undefined behavior. Once you've compiled your invalid code (using either of the first two methods - BTW please never do this), running it will often give you a "segmentation fault" (seg fault). However, it doesn't have to and there are no guarantees as to what your program will do. All variables, including pointers, need to be initialized.

BTW, if you look at this post, it tells you why you need to call malloc here at all -- its because you're allocating memory dynamically, so it will be in the heap rather than on the stack.

1 Comment

Very helpful! Thanks!
1

CASE I:
Code:

int *ptr;
*ptr = 1000;

*ptr means you are dereferencing ptr pointer. Dereferencing an uninitialised pointer is undefined behaviour. An undefined behavior includes it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.

CASE II:
Code:

int *ptr = malloc(sizeof(int));
*ptr = 1000;

malloc allocates memory block (of size in bytes) and returns the pointer to the beginning of newly allocated memory on success. The newly allocated block of memory is not initialised.

When doing this:

int *ptr = malloc(sizeof(int));

Assume malloc call is success and it returned pointer to beginning of newly allocated memory. This returned pointer will be assigned to ptr pointer. So, now the ptr pointer is initialised though the memory it is pointing to is uninitialised.
Since, the ptr pointer is pointing to a valid memory location, you can dereference it and access it.

In this statement

*ptr = 1000;

dereferencing ptr and assigning 1000 to that memory location. Now, the memory location which ptr pointer is pointing to contain value 1000. Accessing this value perfectly fine.


Additional:

Follow the good programming practice - Always check the malloc return. You should do:

  int *ptr = malloc (sizeof (int));
  if (NULL == ptr) {
    exit(EXIT_FAILURE); // or whatever you want to do at malloc failure do it here
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.