-1

I'm trying to figure out how pointers work with allocating memory to them and declaring them, although I kinda know how they work, I'm still getting confused and I'm not sure if it's because of my compiler or something.

I currently use CodeBlocks with GNU/GCC compiler as default, and this is the code I'm running:

#include <stdio.h>

int main()
{
    int a = 2;
    int *b = 5;
    printf("%d\n", a);
    printf("%d\n", b);
}

The problem is that both of these write out correct result, why would I need to use malloc if I can just write out *b = 5 and declare it like that, isn't the purpose of malloc to allocate memory to a pointer so you can declare it after?

Is it compilers fault that it allows this to compile or I'm just not getting the point of malloc?

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • `int* b= 5;` is invalid. Sure it will print the pointer but anything it accesses is random in your case which could result in exceptions. You don't know what's at memory address 5 – Irelia May 01 '21 at 23:21
  • Before you do anything else, configure the compiler to give an error for this invalid code. Otherwise it just makes you waste time running invalid code . – M.M May 02 '21 at 11:40

2 Answers2

2

The problem is that both of these write out correct result, why would I need to use malloc if I can just write out *b = 5 and declare it like that, isn't the purpose of malloc to allocate memory to a pointer so you can declare it after?

You can write pointers to existing memory in which you already know what data/code exists there. In your case you're just making a pointer point to 5.. And you have no idea what's at memory address 5.

I think you're slightly confused on what memory allocation is actually doing. It's not magically making memory appear for you to use, it's using something called the heap to make memory accessible aka read/write and depending on what permissions you give possibly executable. You allocate memory so you can use that memory region. If you don't allocate memory and just access a random memory region, you have no idea what will happen. Most likely it will just crash. But you could also be accessing/overwriting existing critical information to the process.

Let's assume calling malloc returns the address 0xCAFE. This means that address or region of memory is made accessible for us. But we know 0xCAFE already exists in the process memory, could we not just make a pointer point to it and use it? No, because you have no idea if that region is accessible or if it's already being used (allocated by a previous call to malloc) or it may be used in the future (allocated by a future call to malloc) in which you'll result in corrupt memory.

Irelia
  • 3,407
  • 2
  • 10
  • 31
  • Thanks for your time and answer, the other answer explained it slightly better for a newbie like me to understand, but I appreciate your answer too! ♥ – Adi Kešetović May 01 '21 at 23:50
1

The fact that the result is what you expect doesn't mean the code is correct, your program is ill-formed, in int *b = 5, you are assigning the value of 5 to a pointer, this will be interpreted as a memory address, that's what pointers are used for, so you can use that memory address to access the data, and, for instance, pass it as a function argument so that the data can be manipulated.

If you want to just store an int you would use an int variable, so, whilst not illegal, it doesn't make much sense, and deferencing the pointer will invoke undefined behavior, so you can't really use it as a pointer, which is what it is.

You use malloc so that your program and that specific pointer can be given(assigned) by the system a workable memory address where you can store data for later use, (5 is almost certainly not that).

printf("%d\n", b) is also incorrect, the specifier to print a pointer value i.e. a memory address is %p, that is definitely undefined behavior, the correct expression would be:

printf("%p\n", (void*)b);

C gives the programmer leeway to do things that other programming languages don't allow, that is an advantage, but it can also be a problem, programs that compile and seem to run properly may be problematic. When an ill-formed program complies and runs its behavior falls in the category of undefined behavior.

This is defined in the standard and gives the compilers discretionary power to treat the code in any way it sees fit, that includes producing a seemimgly correct result, the problem is that this may work today, and crash tomorrow or vice-versa, it is completely unreliable.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • Thanks for your answer! So if I'm getting this right, by declaring pointer b to 5, I'm just declaring its address to 5 and when I'm printing it with int format specifier it ignores all the other 0s in address and prints last one which is 5, so it looks like correct output while it's not actually? – Adi Kešetović May 01 '21 at 23:37
  • @AdiKešetović, exactly, I couldn't have put it better myself. – anastaciu May 01 '21 at 23:38
  • Well now it makes a lot of sense, thanks for your time and answer, this is the second time that you're helping me this week. :) – Adi Kešetović May 01 '21 at 23:47
  • @AdiKešetović, so it is, maybe some day you'll come here and pay back by helping some fellow programmer in need of assistance. I like your curiosity, it will take you far, for sure. – anastaciu May 01 '21 at 23:58