-1

I'm not a C programmer so please be understanding ;)

C language has pointers and all of its goodness. But how a primitive type declaration works?

For example I can do:

char x = 'a';

There are no pointers there but the value must be stored somewhere in memory, right? Can I think of above statement as translated to:

char* _x = malloc(sizeof(char));
char x = *_x;
marzelin
  • 10,790
  • 2
  • 30
  • 49
  • 1
    In that case, where is `_x` stored? – klutt Sep 04 '18 at 11:56
  • 2
    Not, not at all. What makes you think so? – Jabberwocky Sep 04 '18 at 11:57
  • @Broman hmm... nowhere? at execution they are replaced with the memory address – marzelin Sep 04 '18 at 11:57
  • 4
    Possible duplicate of [Difference between static memory allocation and dynamic memory allocation](https://stackoverflow.com/questions/8385322/difference-between-static-memory-allocation-and-dynamic-memory-allocation) – Sander De Dycker Sep 04 '18 at 11:58
  • Well, in this case the compiler might optimize it, but that's a completely different story. `x` will be a `char` variable. `_x` will be a pointer variable. – klutt Sep 04 '18 at 12:01
  • 1
    By your explanation, the value of that pointer must also be stored somewhere in memory too, right? So wouldn't that _actually_ be `char** __x = malloc(sizeof(char*)); ...` /s – Patrick Roberts Sep 04 '18 at 12:04
  • @PatrickRoberts so what happens when I reference a variable that its value is stored in the stack? Do I get a memory location that's on the stack? – marzelin Sep 04 '18 at 13:22

5 Answers5

4

No, you can't .

malloc(sizeof(char));

Will allocate memory in the heap, which you're in charge of deleting it . One of the benifits of this, is that the data in allocated memory won't "die" when his scope ends, it will only die when you destruct it .

char c = 'a'

Will be stored in the stack , and will automatically be released when its scope ends.

EDIT: Regarding your comment, in general , local variables will usually be stored in the stack(this is ofcourse , automatic) . malloc , calloc allows you to "ask" for space in the heap, and use it as you wish . If you want more info, you can look here , as mentioned by @Jabberwocky

bobra
  • 615
  • 3
  • 18
sagi
  • 40,026
  • 6
  • 59
  • 84
  • so the primitive values are kept in the stack because they have small size, yes? – marzelin Sep 04 '18 at 11:59
  • 3
    @marzelin no, the size is totally unrelated. All local variables are allocated on the stack (at least more or lless). You'd best start reading a C text book. – Jabberwocky Sep 04 '18 at 12:00
  • @Jabberwocky I wish I had time for that ;) – marzelin Sep 04 '18 at 12:00
  • @marzelin the duplicate mentioned in your question's comment contains the info you need. – Jabberwocky Sep 04 '18 at 12:01
  • variable will die, but allocated memory will stay – bobra Sep 04 '18 at 12:43
  • oh cool, values on the stack are automatically cleared but I have to take care to clear values stored on the heap. That's one of the differences between a stack and heap. In high-level languages all values are garbage collected automatically (so there's not much difference between the two). That's what I've been missing. Thanks. – marzelin Sep 04 '18 at 14:53
  • No problem.. Yes , high level languages have their benefits .. but that is because someone wrote you the code that does this automatically. Low level languages have their benefits as well . – sagi Sep 04 '18 at 15:18
  • One of the benefits is that they don't hide tricky details behind abstractions. Those details are sometimes very important and quite interesting ;) – marzelin Sep 04 '18 at 15:29
  • 1
    Note that the C language definition says *nothing* about stacks or heaps - it only specifies *behavior* of different types of variables. It turns out that the best way to implement the behavior of `auto` variables is to use a stack, but that's not *mandatory*. – John Bode Sep 04 '18 at 16:00
  • @JohnBode: The best way is *generally* to use a stack, but in some cases other approaches may work better. Using a stack, for example, would require that a system pre-allocate enough contiguous address space to accommodate worst-case stack usage. An implementation that kept a linked list of storage blocks allocated via some other mechanism could avoid having to assign the stack address space that would never actually get used. – supercat Sep 04 '18 at 19:44
2

There are no pointers there but the value must be stored somewhere in memory, right?

In that particular case (char x = 'a';) it is likely that the value would practically be stored only inside a processor register. But the program behave "as-if" x was in some memory location.

In practice, read How To Debug Small Programs and look into some C reference site. If you want to understand more precisely the (tricky) semantics of C11, refer to its standard n1570, and look into the Compcert project and into static source code analyzers like Frama-C. Memory semantics of C is tricky.

Read also about automatic variables, their scope, and the call stack. Read also about storage class specifiers (auto is the default storage duration). Take time to understand what is undefined behavior and be scared of it.

PS. Your imaginary code lacks some free(_x) and that is really important and you should ask yourself where is that _x stored! But don't expect us to teach you C (an entire book is needed).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thanks for the answer. Now I know that `_x` like any other identifier has its value stored in the stack. Pointers are for the heap (generally). – marzelin Sep 04 '18 at 14:45
  • Pointers are not necessarily in the heap, depends where you point them (the address of the pointer it self is too stored in the stack. Consider : ‘int x = 1; int * y = &x;’ y will be stored in the stack and as well will point to memory in the stack @marzelin – sagi Sep 04 '18 at 15:14
  • Indeed, but the OP used `malloc` – Basile Starynkevitch Sep 04 '18 at 15:24
  • so there's an internal mapping mechanism that pairs identifiers with memory addresses. When compiler sees `x` it provides its value to be done something with in the instruction. But I can also get the memory address of that identifier with `&x`. Those are automatic mappings, but I can have manual mappings that I control thanks to pointers. Wonderful! – marzelin Sep 04 '18 at 15:27
1

Here

char x = 'a';

There are no pointers there but the value must be stored somewhere in memory, right? Yes there are no pointers but x is local variable and it's stored in stack section of primary memory i.e x does have valid memory.

Can I think of above statement as translated to: char* _x = malloc(sizeof(char));

char x = *_x;

No you can't as x here is allocated in heap section. So you can't think both scenario as same. And what *_x holds ? Garbage. You need to add one more statement after allocating memory

*_x = 'a';

Achal
  • 11,821
  • 2
  • 15
  • 37
1

You shouldn't care.

What you need to know is that

char x = 'a';

declares x as a char type with automatic storage duration and sets the int constant 'a' to it, the value of which depends on the encoding your platform uses, but must not overflow a char.

Whether or not that survives compilation is another matter entirely. Perhaps your compiler substitutes the number 'a' whenever you write x in your source code; particularly if x never changes?

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • You're right that I don't need to know that to write code but I'm more interested in knowing how the 'magic' behind translating code into something that computer understands works. – marzelin Sep 04 '18 at 12:14
  • 1
    @marzelin: But you're up a gum tree if you're expecting every variable to be compiled in. Do study the *As-if rule* for compilation. – Bathsheba Sep 04 '18 at 12:15
1

This is a simple question with a very complicated answer.

Actually, you're asking two different questions - how storage is allocated for a variable, and how the variable's name is associated with that storage.

As for the first question, the C language definition doesn't specify the mechanics of how storage for variables is actually allocated - that depends on the compiler, executable file format, and operating system. You'll hear people talk about "stack" and "heap", but there's nothing in the C language definition that mandates the use of a stack or a heap to manage variables and other objects.

As to the second question, the answer (usually) is, "it isn't." Variable names are not preserved in the generated machine code. Instead, the machine code will usually refer to that object via an offset from some address stored in a register.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • does it store information about the type of a variable in the compiled code or if the types are relevant only while compiling? And since I can dereference any variable like: `int a = 1; int* b = &a;` it means that at that memory location for `a` (offset from some address) isn't the value of `a` directly but the address where `1` is. Right? – marzelin Sep 04 '18 at 22:02
  • @marzelin: Types are only relevant during compilation. No metadata (size, type, name, etc.) is required to be stored with the variable in the machine code, although compilers may do so for debugging purposes. – John Bode Sep 04 '18 at 22:20