0

Char pointer's memory allocation via calloc works as expected only when I do not assign some value to the pointers.

I am trying to get some simple examples working to better my understanding of pointers / double pointers / triple pointers / ... . While writing the code for double pointers, I stumbled upon a really weird behavior.

#define PRINT(X, ...) printf("Address of " X "\n", ##__VA_ARGS__);

...
...

    int i = 0;
    char buf[12];
    char **two_star;

    two_star = calloc(10, sizeof(char*));
    for (i = 0; i < 10 ; ++i){
        two_star[i] = calloc(10, sizeof(char));
        PRINT("two_star[%d]   = %p", i, two_star[i]);
    }

    for (i = 0; i < 10 ; ++i){
        two_star[i] = calloc(10, sizeof(char));
        snprintf(buf, 12, "pre_%d_suff", i);
        two_star[i] = buf;
        PRINT("two_star[%d]   = %p   two_star[%d]   = %s", i, two_star[i], i, two_star[i]);
    }

I get the following results for the above two for loops:

For Loop 1:

Address of two_star[0]   = 0xbcc090
Address of two_star[1]   = 0xbcc0b0
Address of two_star[2]   = 0xbcc0d0
Address of two_star[3]   = 0xbcc0f0
Address of two_star[4]   = 0xbcc110
Address of two_star[5]   = 0xbcc130
Address of two_star[6]   = 0xbcc150
Address of two_star[7]   = 0xbcc170
Address of two_star[8]   = 0xbcc190
Address of two_star[9]   = 0xbcc1b0

For Loop 2:

Address of two_star[0]   = 0x7ffcd2238ab0   two_star[0]   = pre_0_suff
Address of two_star[1]   = 0x7ffcd2238ab0   two_star[1]   = pre_1_suff
Address of two_star[2]   = 0x7ffcd2238ab0   two_star[2]   = pre_2_suff
Address of two_star[3]   = 0x7ffcd2238ab0   two_star[3]   = pre_3_suff
Address of two_star[4]   = 0x7ffcd2238ab0   two_star[4]   = pre_4_suff
Address of two_star[5]   = 0x7ffcd2238ab0   two_star[5]   = pre_5_suff
Address of two_star[6]   = 0x7ffcd2238ab0   two_star[6]   = pre_6_suff
Address of two_star[7]   = 0x7ffcd2238ab0   two_star[7]   = pre_7_suff
Address of two_star[8]   = 0x7ffcd2238ab0   two_star[8]   = pre_8_suff
Address of two_star[9]   = 0x7ffcd2238ab0   two_star[9]   = pre_9_suff

The issue here is evident. The pointers being allocated in the second for loop all have the same value of address. Meaning, that two_star[0] and two_star[9] end up being the same value as the same memory address ends up being updated again and again.

1
  • 3
    memcpy instead of two_star[i] = buf; Commented Sep 11, 2019 at 21:51

2 Answers 2

2

Use strcpy: strcpy(two_star[i], buf); instead of two_star[i] = buf;, because in your case you don't copy string, just reassign pointer two_star[i] to buf (and here is also memory leak, because you've lost pointer to allocated memory).

Sign up to request clarification or add additional context in comments.

1 Comment

This works. Will accept it as the correct answer when time permits.
1

Using strcpy(two_star[i], buf); is insufficient.

    char buf[12];
    two_star[i] = calloc(10, sizeof(char));
    // snprintf(buf, 12, "pre_%d_suff", i);
    strcpy(two_star[i], buf);  // bad, trying to put 12 characters into 10
    two_star[i] = buf;

The destination is too small.

Instead, code could right size.

   int size_needed = snprintf(NULL, 0, "pre_%d_suff", i)  + 1;
   two_star[i] = malloc(size_needed);
   snprintf(two_star[i], size_needed, "pre_%d_suff", i);

Note: Error checking omitted for brevity.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.