3

I have a function written in C which consist of a pointer variable like this

#include<stdio.h>
void print()
{
    char *hello="hello world";
    fprintf(stdout,"%s",hello);
}

void main()
{
    print();
    print();
}

if i call the print() function twice, will it allocate the memory for the hello variable twice?

  • It depends on what you mean by *the memory for the hello variable*. Do you mean the memory for the string *data* ("hello world"), or the memory used for the variable itself (which will store the *address* of that data)? – Adrian Mole Sep 18 '20 at 13:04
  • i mean the total space required to store the string – Selastin George Sep 18 '20 at 13:05
  • 1
    That will most likely be implementation defined. Most modern systems will create space for the (constant) string literal data, and initialize that, at compile time. But they are not obliged to. (I think.) – Adrian Mole Sep 18 '20 at 13:06
  • yes, it will. but I think it depends on the compiler. – mohammad jalili Sep 18 '20 at 13:07

4 Answers4

8

if i call the print() function twice, will it allocate the memory for the hello variable twice?

No, it's a string literal and allocated just once.

You can check that by checking the address:

fprintf(stdout,"%p: %s\n", hello, hello);

Sample output:

0x563b972277c4: hello world
0x563b972277c4: hello world
artm
  • 17,291
  • 6
  • 38
  • 54
3

if i call the print() function twice, will it allocate the memory for the hello variable twice?

Yes. However, hello is a pointer and takes up 8 bytes of stack space on a 64 bit machine. The cost is effectively not measurable. Furthermore, the compiler doesn’t necessarily need to allocate the variable at all, since you never attempt to take its address. The compiler is free to effectively transform your code into:

void print()
{
    fprintf(stdout, "%s", "hello world");
}

Meaning that the declaration of hello will not result in any memory allocation at runtime. not For all intents and purposes, having hello as a local variable is cost-free.

By contrast, the zero-terminated string literal "hello world" is only allocated once, in the data segment of the application. The compiler can do this because it knows that C string literals are readonly, so nothing is allowed to modify it. Furthermore, no dynamic memory allocation is performed at runtime. The memory for the string literal is allocated statically, and its lifetime is the lifetime of the application.

Consequently your print function is essentially as cheap as it can get — it does not perform any actual allocations at all.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
2

You can paste the code at compiler explorer to see what happens. From your code, this is the assebler generated:

print():                              # @print()
        mov     rcx, qword ptr [rip + stdout]
        mov     edi, offset .L.str
        mov     esi, 11
        mov     edx, 1
        jmp     fwrite                  # TAILCALL
main:                                   # @main
        push    rax
        mov     rcx, qword ptr [rip + stdout]
        mov     edi, offset .L.str
        mov     esi, 11
        mov     edx, 1
        call    fwrite
        mov     rcx, qword ptr [rip + stdout]
        mov     edi, offset .L.str
        mov     esi, 11
        mov     edx, 1
        call    fwrite
        xor     eax, eax
        pop     rcx
        ret
.L.str:
        .asciz  "hello world"

The important part is at the end:

.L.str:
        .asciz  "hello world"

The "hello world" is declared only there like a global variable, and is used every time you call the function print.

It is like if you declared it like this:

#include<stdio.h>

const char* hello = "hello world";

void print()
{
    fprintf(stdout,"%s",hello);
}

void main()
{
    print();
    print();
}

In this case, the compiler saw the optimisation and made it. But, I cant say for sure this will always be the case, because it cant depend on the compiler.

Pablochaches
  • 968
  • 10
  • 25
0
  1. hello variable

Automatic variables end their lifes when function exits. So the memory is only allocated on the stack when your are inside the function. It is going to be freed when function exists.

  1. the string literal has program lifetime and is somewhere where literals are stored (usually .rodata segment). This area is filled during the program building and how actually it is represented in the memory depends on the implementation
0___________
  • 60,014
  • 4
  • 34
  • 74