0

I am confused by how this C program is running. I am just trying to use a structure to store some variables and then be able to print them out in a separate function. Below is my code. What I don't understand is why is my first output includes both ip and key and not just ip.

#include <stdio.h>

struct device {
    char ip[6];
    char key[5];
};

void check(struct device cred);

int main ()
{
    int i;
    struct device cred[10];

    strcpy(cred[0].ip, "192.16");
    strcpy(cred[0].key, "45EA9");

    check(cred[0]);
    return 0;
}

void check(struct device cred)
{
    printf("IP: %s\n", cred.ip);
    printf("Key: %s\n", cred.key);
}

Output:

IP: 192.1645EA9
Key: 45EA9
5
  • 1
    Hint: IPv4 addresses are a lot longer than six characters. Don't forget the terminator character, either.
    – tadman
    Commented Feb 26, 2018 at 21:23
  • 2
    You are overflowing ip, it should be char ip[7] to hold the '\0'-terminating byte. Same for key.
    – Pablo
    Commented Feb 26, 2018 at 21:24
  • How were you expecting printf to know where to stop? Commented Feb 26, 2018 at 21:25
  • A string is a character sequence including a 0-valued terminator; you need to set aside at least N+1 elements to store an N-character string. Since the terminator wasn't there, printf just kept going and printed the contents of key.
    – John Bode
    Commented Feb 26, 2018 at 21:28
  • Note that if you reversed the order of the strcpy() operations, you'd probably get nothing printed for the cred.key. Commented Feb 26, 2018 at 23:43

3 Answers 3

3
strcpy(cred[0].ip, "192.16"); 

is undefined behavior. The target has not enough space for holding the \0. So it writes that out of the array bounds resulting in UB. Same problem is there with key also.

Printing it with %s format specifier will now also be undefined behavior for the very reason described above. printf tries to print the characters starting from the address pointed by the argument passed to it — but it doesn't find the \0 within the array so it reads beyonds the array which is undefined behavior.

You have to make the array size big enough to hold the characters of the string literals including the nul terminating char.

0
1

The answer is: strings in C are one character longer than they appear.
That's because the program has to know where the end of a string is – and this is marked with an additional zero byte (ASCII NUL code) appended.

So, your string "192.16" is actually a 7-byte array whose last byte is zero. When you strcpy it into cred.ip that seventh byte lands outside the array, which invokes an Undefined Behaviour.

In your case apparently the arrays cred.ipand cred.key touch one another, so that terminating NUL byte is stored as the first byte of cred.key. The next moment it gets overwritten by the first character of "45EA9".

This way the first string looses its terminator, and the second one gets effectively appended to it – hence the output consisting of both strings glued.

0

You where allocating less space than you actually needed. Always make sure to allocate +1 for the NULL Character '\0'.

Not the answer you're looking for? Browse other questions tagged or ask your own question.