0

so I'm quite new in this, sorry if it sound like a dumb question

I'm trying to understand malloc, and create a very simple program which will print "ABC" using ASCII code

here is my code (what our professor taught us) so far

char *i;
i = malloc(sizeof(char)*4); 
*i = 65;
*(i+1) = 66;
*(i+2) = 67;
*(i+3) = '\0';

what I don't understand is, why do I have to put malloc there? the professor told us the program won't run without the malloc, but when I tried and run it without the malloc, the program run just fine. so what's the function of malloc there? am I even using it right?

any help and or explanation would be really appreciated

Sae
  • 79
  • 7
  • 1
    Without it, `i` is uninitialized and points to random memory. – melpomene Jun 17 '17 at 12:05
  • 1
    "the program run just fine". It wasn't fine. C has this concept of Undefined Behaviour. Triggering UB (e.g. by accessing invalid memory) results in behaviour that is unpredictable, including appearing to work but can stop working at any time and with any resulting behaviour. – kaylum Jun 17 '17 at 12:06
  • Which means, you might get lucky/unlucky and not spot the problem when running it. – Yunnosch Jun 17 '17 at 12:07
  • Possible duplicate of https://stackoverflow.com/questions/23455003/why-can-i-use-a-char-pointer-without-malloc – Nandakumar Edamana Jun 17 '17 at 12:07
  • Run it 1000 times without malloc and see what happens... – Fusho Jun 17 '17 at 12:07
  • 1
    You should be getting a warning "‘i’ is used uninitialized in this function [-Wuninitialized]" from your compiler. Try `strcpy` with some long string (e.g.: `strcpy(i, "The quick brown fox jumps over the lazy dog.");`) and you should be getting Segmentation Fault. – Nandakumar Edamana Jun 17 '17 at 12:09
  • 1
    If your prof did not elaborate more, you should ask him. if still unclear, get a good C book. `dynamic memory allocation is explained in every beginner's C book! The book will help you with other issues, too. From my experience someone not explaining one aspect fails at others, too. – too honest for this site Jun 17 '17 at 12:10

3 Answers3

4

the professor told us the program won't run without the malloc

This is not quite true, the correct wording would be: "The program's behavior is undefined without malloc()".

The reason for this is that

char *i;

just declares a pointer to a char, but there's no initialization -- this pointer points to some indeterminate location. You could be just lucky in that writing values to this "random" location works and won't result in a crash. I'd personally call it unlucky because this hides a bug in your program. undefined behavior just means anything can happen, including a "correct" program execution.

malloc() will dynamically request some usable memory and return a pointer to that memory, so after the malloc(), you know i points to 4 bytes of memory you can use. If malloc() fails for some reason (no more memory available), it returns NULL -- your program should test for it before writing to *i.

All that said, of course the program CAN work without malloc(). You could just write

char i[4];

and i would be a local variable with room for 4 characters.


Final side note: sizeof(char) is defined to be 1, so you can just write i = malloc(4);.

  • thanks so much! your explanation is so detailed and easy to understand. as for the char i[4], I know I can do it that way too but we need to use pointer for the homework so that's why I'm using it. anyway, thanks a lot! – Sae Jun 17 '17 at 12:30
  • 1
    @Sae YW! In a real-life program, don't forget to `free()` memory you obtained from `malloc()` when you don't need it any more. As your program just exits, omitting `free()` is fine on a modern platform -- but in some real-life project, the execution would continue and failing to call `free()` introduces *memory leaks* (you don't have a pointer any more, but still the memory is allocated) –  Jun 17 '17 at 12:34
  • One way causing a memory leak is to simply assign `i` to something else. There are certain algorithms (typically with loops) where it makes sense to assign a variable more than once but otherwise it's a good habit to assign a well-named variable at declaration, never assign it again, and, of course, free it when done. – Tom Blodget Jun 17 '17 at 23:58
3

Unfortunately, "runs fine" criterion proves nothing about a C program. Great deal of C programs that run to completion have undefined behavior, which does not happen to manifest itself on your particular platform.

You need special tools to see this error. For example, you can run your code through valgrind, and see it access uninitialized pointer.

As for the malloc, you do not have to use dynamic buffer in your code. It would be perfectly fine to allocate the buffer in automatic memory, like this:

char buf[4], *i = buf;
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

You have to allocate space for memory. In the example below, I did not allocate for memory for i, which resulted in a segmentation fault (you are trying to access memory that you don't have access to)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
  char *i;
  strcpy(i, "hello");
  printf("%s\n", i);
  return (0);
}

Output: Segmentation fault (core dumped)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
  char *i;
  /*Allocated 6 spots with sizeof char +1 for \0 character*/
  i = malloc(sizeof(char) * 6);
  strcpy(i, "hello");
  printf("%s\n", i);
  return (0);
}

Result: hello

Malloc allows you to create space, so you can write to a spot in memory. In the first example, "It won't work without malloc" because i is pointing to a spot in memory that doesn't have space allocated yet.

LLL
  • 117
  • 2
  • 12