-2

I've written a small program to concatenate a string "20746865" upto 300 characters. The program is as follows:

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

void main()
{
char test[] = {'2','0','7','4','6','8','6','5'};
char crib[300];
int i, length = 0;
 while(length <= 299)
  {
     for(i=0; i<8;i++)
      {
        crib[length] = test[i];
        i=i%8;
        length++;
      }

  }
crib[length]='\0';
printf("%s", crib);
}

The following is the output:

2074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865207468652074686520746865

However, when i count the number of characters in the output, it shows 304 characters. Could someone help me understand how can it print 304 characters if the array size is only 300?

3
  • 1
    Note that i=i%8 does precisely nothing; your loop will end before it gets to 8. (If it didn't, you'd get an infinite loop.) Commented Sep 13, 2015 at 1:52
  • 296(37*8) + 8(in for-loop) = 304(write overflow) Commented Sep 13, 2015 at 1:56
  • 1
    void main() is wrong Commented Sep 13, 2015 at 3:06

3 Answers 3

1

The bug in your code is that the inner loop continues even when the written index is out of bounds, which causes it to continue until the next multiple of 8 generating undefined behavior.

Unlike previous replies, this version compiles and works according to your description using C99, minimizing the number of copies and iterations.

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

static const size_t OUTPUT_SIZE = 300U;
static const char   INPUT[]     = {'2','0','7','4','6','8','6','5'};
static const size_t INPUT_SIZE  = sizeof(INPUT);

int main()
{
    char output[OUTPUT_SIZE + 1];
    const size_t numIter = OUTPUT_SIZE / INPUT_SIZE;
    size_t idx = 0;

    // copy full chunks
    for (; idx < numIter; idx++)
    {
        memcpy(output + idx * INPUT_SIZE, INPUT, INPUT_SIZE);
    }

    // write the remainder
    memcpy(output + numIter * INPUT_SIZE, INPUT, OUTPUT_SIZE % INPUT_SIZE);

    // add null terminator
    output[OUTPUT_SIZE] = '\0';

    printf("result: %s\nlength: %d\n", output, strlen(output));

    return 0;
}

I hope this helps.

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

Comments

0

You have undefined behavior here. You defined crib as type char[300], but you are indexing it at position 300 when you write crib[length] = '\0'. So it's not clear that your string is actually being null terminated.

Comments

0

You don't make any provision to see if the for loop will kick the length beyond the threshold, but instead only check in the while loop every 8 characters to see if it's already long enough/too long. After 38 complete outer loops, therefore, it hits exactly 304 characters and terminates, since 304 is not <= 299.

What you should probably do is avoid having two loops at all. Instead, keep a loop index and a calculated rolling index based on that. Untested:

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

void main() {
    char test[] = {'2','0','7','4','6','8','6','5'};
    char crib[301];
    for (int i = 0, j = 0; i < 300; i++, j = i % 8) {
        crib[i] = test[j];
    }
    crib[length]='\0';
    printf("%s", crib);
}

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.