here's my code
int wordSize = 8; // defining a word size
int *myArray = NULL;
myArray = malloc(sizeof(char)*(wordSize 1)); // using malloc() so I always have a big enough array should wordSize change. Also to practice.
int index = 0; // defining a variable to browse through myArray
do
{
myArray[index] = '*';
index ;
}
while(index < wordSize);
myArray[wordSize] = '\0'; // filling myArray with '*' character and the null terminator /0
printf("%s", myArray); // trying to display myArray, only a single '*' is printed
printf("\n\n");
int i=0;
while(i < wordSize 1)
{
printf("%c", myArray[i]);
i ;
} // trying to display myArray with an other method, this time with success
Since
char string[] = "hello";
printf("%s", string);
is working perfectly fine, I don't understand why printf("%s", myArray);
isn't working and only displays a single *
. The do/while loop shows 8 *
as expected which means that my array is filled as it should.
EDIT : as asked in the comments, simplified my example as well as tried some solutions and some other possibilities.
CodePudding user response:
I think this is the problem.
int *myArray = NULL;
...
printf("%s", myArray);
You're trying to print an array of integers as if it was a string. I think that, by passing the wrong type of variable to printf()
, you're going to invoke undefined behavior. It's also problematic that you only allocated enough memory for wordSize 1
bytes, and then proceeded to write values into the array as if it was big enough for wordSize 1
integers.
Fix this by changing the definition of myArray
:
char *myArray = NULL;
The rest of the code, that accesses the members of this array, should now change from writing int
values to writing char
values. To be clear, I don't think you'll need to change anything. The compiler should do it for you, once myArray
is properly defined as an array of char
.
ETA: More on what was happening in the original code.
Initially, you allocate 9 bytes. This is enough space for slightly more than 2 integers (assuming that sizeof(int)
is 4). I'm also assuming that this memory was initially filled with zeroes.
The memory allocated to myArray
looks something like this:
myArray[0] 00 00 00 00
myArray[1] 00 00 00 00
myArray[2] 00
Then you go through and store 8 '*' characters in memory, which leaves memory looking like this:
myArray[0] '*' 00 00 00
myArray[1] '*' 00 00 00
myArray[2] '*'
Note that five more asterisks are written into memory that you do not own.
Then a "terminating zero" is written, again outside the memory that was allocated for myArray
.
Then, you pass myArray
— meaning, the address of the first byte in myArray
— to printf()
. It prints the first asterisk, and the next byte it sees is a zero, so it stops.
Finally, you access individual integer members of myArray
as if it was an array of eight integers (even though there isn't enough memory even for three). The observed results are that the asterisks are still where you wrote them, and that the adjacent bytes are apparently all zeroes.
Note that this is all based on assumptions about your development environment, your target architecture, and so on. The exact mechanism for what you observed is potentially interesting — but it is important to remember that it's all examples of undefined behavior. You should not rely upon it, because in a different system or on a different day the results could be radically different.
CodePudding user response:
If testCharacter is initialized with 0
I think you should use character pointer type for displayedSecretWord
and then allocate sizeof(char) * (characterCount 1) for displayedSecretWord.