0

A newbie question:

I was practice assignment to a char pointer, but found there was nothing printed out. Here is the code:

#include <stdio.h>

int main (void)
{
    char * option_string = NULL;
    option_string = (char*)malloc(sizeof(5));
    memset(option_string, 0, sizeof(char) * 5);

    int j;
    for ( j = 0; j < 5; j++)
    {
        *option_string++ = 'a';
    }

    printf("print options_string: %s\n", option_string); //!nothing was printed out!
    free(option_string);
    return 0; 
}

Thanks in advance!

3 Answers 3

11

You increment the pointer option_string which in turn makes it point past the end of string.

Try malloc(6);

for ( j = 0; j < 5; j++)
{
    option_string[j] = 'a';
}

instead.

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

2 Comments

I forgot the pointer changed to point to some garbage. thanks!
Yes, I tried again to same the initialized position to a tem value.
8

Your malloc(sizeof(5)) seems wrong. What is the size of 5? (Hint: It's not 5.)

1 Comment

@tao: No, the size of 5 is not 6 either. 5 is an integer, so sizeof(5) == sizeof(int). However, your buffer needs to be six bytes long in order to hold a null-terminated string of length 5, which doesn't have anything to do with the size of integers.
4

Your problem is that within the loop, you write *option_string++. This means that once the loop is done, you're going to be pointing past the end of the string:

option_string at start
   |
   V
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |    |    |    |
+----+----+----+----+----+
                             ^
                             |
                     option_string at end

Note that this reveals a second problem with your code: strings in C are null-terminated, but this string will eventually contain "aaaaa" and then… who knows? Garbage, most likely, but you can't tell. You need a six-length string. Fixing the first problem means using simple indexing instead: option_string[j] = 'a'. If you really want the *option_string++ method, you'll have to save and restore option_string (char * real_option_string = option_string; ... option_string = real_option_string;), but I wouldn't recommend it. Fixing both of these bugs, and a couple of style things, gives you:

#include <stdlib.h>
#include <stdio.h>

int main (void)
{
    char * option_string = calloc(6, sizeof(char));

    int j;
    for ( j = 0; j < 5; j++)
    {
        option_string[j] = 'a';
    }

    printf("print options_string: %s\n", option_string);
    free(option_string);
    return 0; 
}

The other thing I changed was your malloc usage. I feel like calloc is a better stylistic choice here; calloc(count, size) allocates count objects of size size, and zeros them. It's like malloc(count*size) plus a memset, but feels cleaner to me. You also shouldn't have a cast on malloc/calloc/etc., generally speaking (it can obscure useful warnings), and you need to allocate six slots, like I said (so you can have the null-terminator, which is the zero-valued character, so we don't need to set it explicitly). Combine that with the option_string[j] indexing mode, include the missing stdlib.h for calloc (you should have had it for malloc, too), and we're good to go!

3 Comments

Great, thanks! Here I added a temp var to store the initialized position of option_string. recover it before printing.
@tao: You're welcome! Is there any particular reason you're using that method? I think it's the worse of the two options, although it will definitely work.
Sorry for late reply! No special reason, I was just practicing the pointer. Thanks again!

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.