Home > OS >  Printing the value of memory allocated by calloc not initialized to zeroed
Printing the value of memory allocated by calloc not initialized to zeroed

Time:09-29

I'm confused about what is happening when I try to use calloc as opposed to malloc. My understanding is that calloc allocates the memory and initializes the value at each address to zero, whereas malloc just allocates the memory. However, when I attempt to print the values at each address I expect the values to be zero for calloc and random characters for malloc - But they aren't... they're the same no matter which I do.

typedef struct {
    char* text;
    void* obj;
} statement_t;

void* stalloc() {
    return calloc(1, MODEL_OBJ_CAPACITY);
    // return malloc(MODEL_OBJ_CAPACITY); Also used this
};

statement_t NewStatement(char* text) {
    statement_t statement;
    statement.text = text;
    statement.obj = stalloc();

    return statement;
};


int main(void) {
    statement_t statement = NewStatement("CREATE job Manager");

    for(int n = 0; n < 10;   n) {
        printf("statement[%d]: %c\n", n, (char)&statement.obj[n]); // Note I've tried a number of ways to print this but they always end up being the same
    }

    ...
}

Output from calloc:

statement: CREATE job Manager 0x7fb127405c60 8
statement[0]: `
statement[1]: a
statement[2]: b
statement[3]: c
statement[4]: d
statement[5]: e
statement[6]: f
statement[7]: g
statement[8]: h
statement[9]: i

Output from malloc:

statement: CREATE job Manager 0x7f8becc05c60 8
statement[0]: `
statement[1]: a
statement[2]: b
statement[3]: c
statement[4]: d
statement[5]: e
statement[6]: f
statement[7]: g
statement[8]: h
statement[9]: i

As you can see, they are the same... What am I missing?

CodePudding user response:

obj has type of void*. C standard does not allow any pointer arithmetics on void pointers. There is not possible to index void *.

It is is a gcc extension and it is not portable.

Try:

printf("statement[%zu]: %d\n", n, ((char *)statement.obj)[n]);

or

    int c;

    for(size_t n = 0; n < 10;   n) {
        c = ((char *)statement.obj)[n];
        printf("statement[%zu]: %s : %d (0xx)\n", n, (c >= 32 && c <= 127) ? (char []){'\'', c, '\'', 0} : "not printable", c, c ); 
    }

CodePudding user response:

You're not printing correctly:

printf("statement[%d]: %c\n", n, (char)&statement.obj[n]); 

You're attempting to print the address of each byte in the array, rather than the byte itself. Also, by using %c you're printing the character associated with each byte value instead of the actual value.

First cast the void * to char *, then index the array. Also, use %d to print the value of each byte:

printf("statement[%d]: %d\n", n, ((char *)statement.obj)[n]); 
  • Related