Home > front end >  Read-Only Memory vs Heap Memory in Memory Usage in C
Read-Only Memory vs Heap Memory in Memory Usage in C

Time:10-02

Assume we have a Struct NODE with

typedef struct tNODE {
    struct tNODE* parent;
    char* inner_text;
}NODE;

Here we have a Read-Only Memory usage of initialization

NODE* temp = new_node(parent);
temp->inner_text = "something";

Vs. Heap Memory usage of initialization

NODE* temp = new_node(parent);
temp->inner_text = strdup("something");

So what I am doing in my program is that, I am parsing through an XML file(the original node struct has more components).

My question is that if I am using read-only memory I have noticed from Valgrind that the total Heap usage is a bit lower than when I am using Heap Allocation.

Is that always true ? why is that ? I work with large files(>3GB), should I take that into consideration ?

CodePudding user response:

In your "Heap Memory usage" example ...

NODE* temp = new_node(parent);
temp->inner_text = strdup("something");

... you require at least double the storage for the string, because you actually have two. strdup() will dynamically allocate memory for a copy of the contents of the string literal, but you still have the string literal too (else, what do you think strdup() could copy from?).

This is not a question of string literal vs. not. I anticipate that you would observe similar memory usage (in both examples) if you replaced the string literal with an explicit, modifiable array such as this:

char something[] = {'s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', '\0'};

If the underlying question is about how to initialize modifiable arrays, then you would probably find this more convenient:

char something[] = "something";

If that appears at file scope, then there is a fair chance that no additional storage is consumed beyond that for your writable array.

CodePudding user response:

The string "something" is (obviously) known at compile time, right?

So, instead of assigning a string literal, introduce a global variable like const char *something = "something"; and assign that to the field of the node.

Even if you assign the (literal) same string, the compiler will probably figure this out and will take care of the above step.

At least GCC (12.2.0) does that on my system, test it out:

struct foo { char *value; };

void processFoo(struct foo *bar)
{
    printf("%p\n", bar->value);
}

int main()
{
    struct foo f1 = { .value = "hello" };
    processFoo(&f1);

    struct foo f2 = { .value = "hello" };
    processFoo(&f2);

    printf("\n");

    for (int i=0; i < 3;   i) {
        struct foo *bar = malloc(sizeof(struct foo));
        bar->value = "hello";
        processFoo(bar);
        free(bar);
    }

    return 0;
}

Output:

0x55b6389f4008
0x55b6389f4008

0x55b6389f4008
0x55b6389f4008
0x55b6389f4008
  • Related