Ruli
Ruli

Reputation: 2780

C char array has different length than expected

I have a very simple code:

secret[]="abcdefgh";//this is declared in different function and is random word
int len=strlen(secret);//ofc it is 8 in this case
char word[len];
for(int a=0;a<len;a++){//expecting this will put '_' at positions 0-7
    word[a]='_';
}
printf("%d %s",(int)strlen(word),word);

However, strlen(word) returns 11 and word contains "________� @", thus there is some obvious memory leak I can't see. Any idea?

Upvotes: 1

Views: 698

Answers (5)

OhadM
OhadM

Reputation: 4803

At first glance it seems you have forgot to put null at the end of your char array (pointer).

From my experience this leads to buffer overruns or stack corruption .

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 310940

This character array initialized by a string literal

secret[]="abcdefgh";

has 9 elements because it also includes the terminating zero of the string literal. So the definition above is equivalent to

secret[9]="abcdefgh";

Function strlen returns the number of elements of a character array that are before the terminating zero. So in this declaration

int len=strlen(secret);

variable len is initialized by 8 As result declaration

char word[len];

is equivalent to

char word[8];

In this loop

for(int a=0;a<len;a++){//expecting this will put '_' at positions 0-7
    word[a]='_';
}

all elements of the aray are set to '_'. The arry does not have the terminating zero. So applaying function strlen to the array has undefined behaviour.

You could change the loop the following way

int a = 0;
for(;a<len - 1;a++){//expecting this will put '_' at positions 0-7
    word[a]='_';
}
word[a] = '\0';

In this case function strlen would return number 7 and the program would be well-formed.

Upvotes: 4

Yasir Majeed
Yasir Majeed

Reputation: 741

One addition and one modification

  1. char word[len]; needs to be changed with char word[len+1];
  2. Add a line world[len] = '\0'; before the last printf line.

That will be it

Upvotes: 1

pmg
pmg

Reputation: 108968

No space for the '\0'.

// "abcdefgh"
//  01234567

You need to define word with space for the NUL terminator.

char word[len + 1];
// "abcdefgh"
//  012345678 -- word[8] gets '\0'

Upvotes: 0

Sadique
Sadique

Reputation: 22823

You just need to nul terminate the string, increase len by 1 and nul terminate your string.

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

int main(void) 
{
    char secret[]="abcdefgh";
    int len=strlen(secret);
    char word[len+1];
    for(int a=0;a<len;a++)
    {
        word[a]='_';
    }
    word[a]=0; //or word[a]='\0'
    printf("%d %s",(int)strlen(word),word);
    return 0;
}

Regarding memory leak yes it can.

Upvotes: 3

Related Questions