1

I'm trying to generate the following output:

0.1

0.12

0.123

0.1234

...

0.123456789

My code uses string/char arrays and some pointer data types that I'm not familiar with.

Code was taken from here to help get started, but I get the following output of gibberish.

CMD Output

Here is the code:

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

int main()
{
    char *str = "0.";
    char digit = '0';

    size_t len = strlen(str);

    int i = 1;


    while(i<10)
    {
        printf("i: %d\n",i);
    
        char *temp = malloc(len + 1 + 1);
    
        len = strlen(temp);
    
        digit = i + '0';
    
        temp[len] = digit;
    
        char string[len];
    
        strcpy(string,temp);
    
        free(temp);
    
        printf("%s\n\n",string);
    
        i = i +1;
    }
}

What needs to be modified to get the data types to work correctly together?

1
  • 3
    temp points to the malloc allocated memory but no string is stored in it, so strlen(temp) will result in some random value... Commented Aug 21, 2020 at 4:23

2 Answers 2

1

As already pointed out by @isrnick, the problem is that you allocate memory but don't initialize it before calling strlen.

It is in general not a good idea to repeatedly alloc/free memory as it fragments the heap. It is better to allocate once in the beginning, reuse the memory and free it in the end.

A better and neater solution would be to keep it on the stack:

#include <stdio.h>

int main()
{
    char str[64] = "0.";

    for (int i = 1; i < 10; i++) {
        str[1 + i] = '0' + i;
        printf("%s\n", str);
    }

    return 0;
}

Output:

0.1
0.12
0.123
0.1234
0.12345
0.123456
0.1234567
0.12345678
0.123456789
Sign up to request clarification or add additional context in comments.

2 Comments

Do you think it would be better to keep it on the stack if you wanted the code to handle strings up to 100+ digits?
For small array lengths (<= 512) I would keep it on the stack, it's hard to give a general answer because it depends on your system and the application. It is in general bad to repeatedly alloc/free small amounts of memory. It fragments the memory and it's also harder to keep track of it (imagine a larger system with multiple files). It's better to allocate a single junk, reuse it and free it at the end.
-1

As @ismick mentioned, temp points to unintialized memory and so can contain anything. A safer bet, especially for 0-terminated strings like C, is to use calloc.

It's also quite a bit simpler to use sprintf rather than strcpy.

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

int main()
{
    char *str = "0.";

    size_t len = 2;

    for (int i = 1; i < 10; i++) {
        printf("i = %d\n", i);                                                                            
        len = len + 2;

        char *temp = calloc(len, sizeof(char));
        sprintf(temp, "%s%d", str, i); 
        if (i > 1) free(str); // string literal when i=1
        str = temp;
        printf("%s\n\n", str);
    }
    free(str);
}

A few new things here: for(int i = 1; i < 10; i++) or for(int i = 1; i < 10; i = i+1) are a handy shortcut for the common construction

int i = 1;

while (i < 10) {
  ....
  i = i + 1;
}

We use calloc to get a pointer to a block of memory that's initialized with 0; the second sizeof(char) parameter tells us to get a block that fits len-many chars.

We use sprintf(temp, "%s%d", str, i); to ease copying the previous value of str into this new block of memory plus the next digit, e.g. 0. ~~> 0.1 or 0.12 ~~> 0.123.

Finally, we set str = temp; to point str to the start of temp, so we don't lose the copied/concatenated string we just made using sprintf.

edit: add comments about code
edit 2: fixed the double free pointed out in the comments.

4 Comments

Sadly, I forgot to free(temp) at the last line of the for loop, and then free(str) at the end of main!
this crashes, you free the str twice.
you also use str when it still points to the free'd temp, therefore it produces funny output.
You're right! I compiled it first without any free, and it produces the intended output. Then I carelessly tried to fix it on my phone. Thanks.

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.