printf 没有正确显示我的字符串 - 为什么?
printf doesn't display my string correctly - why?
这是我的代码
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] = '[=10=]'; // 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
自
char string[] = "hello";
printf("%s", string);
工作得很好,我不明白为什么 printf("%s", myArray);
不工作,只显示一个 *
。 do/while 循环按预期显示 8 *
,这意味着我的数组已按预期填充。
编辑:如评论中所述,简化了我的示例并尝试了一些解决方案和其他一些可能性。
如果testCharacter初始化为0
我认为你应该为 displayedSecretWord
使用字符指针类型
然后为displayedSecretWord分配sizeof(char) * (characterCount+1)。
我认为这是问题所在。
int *myArray = NULL;
...
printf("%s", myArray);
您正在尝试打印一个整数数组,就好像它是一个字符串一样。我认为,通过将错误类型的变量传递给 printf()
,您将调用 未定义的行为。同样有问题的是,您只为 wordSize+1
字节 分配了足够的内存,然后继续将值写入数组,就好像它足够大 wordSize+1
整数.
通过更改 myArray
的定义来解决此问题:
char *myArray = NULL;
访问此数组成员的其余代码现在应该从写入 int
值更改为写入 char
值。需要明确的是,我认为您不需要更改任何内容。一旦 myArray
被正确定义为 char
.
的数组,编译器应该为您完成
预计到达时间:
更多关于原始代码中发生的事情。
最初,您分配了 9 个字节。这足以 space 用于略多于 2 个整数(假设 sizeof(int)
是 4)。我还假设这个内存最初是用零填充的。
分配给 myArray
的内存看起来像这样:
myArray[0] 00 00 00 00
myArray[1] 00 00 00 00
myArray[2] 00
然后你遍历并在内存中存储 8 个'*'字符,这使得内存看起来像这样:
myArray[0] '*' 00 00 00
myArray[1] '*' 00 00 00
myArray[2] '*'
请注意,另外五个星号已写入您不拥有的内存中。
然后写入“终止零”,再次写入分配给 myArray
.
的内存之外
然后,你将 myArray
——也就是说,myArray
中第一个字节的地址——传递给 printf()
。您使用了 %s
格式说明符,因此它将打印一个字符串。在打印第一个字节(星号)后,它看到的下一个字节是零,因此它停止了。
最后,您可以访问 myArray
的各个整数成员,就好像它是一个由八个整数组成的数组(即使没有足够的内存容纳三个整数)。这意味着,代码将对应于 myArray[0]
的四个字节读入一个临时整数,并将其值打印为一个字符(因为 %c
格式说明符传递给 printf()
).随着循环的继续,后面的内存区域将被读取,包括不属于您的内存。观察到的结果是星号还在你写的地方。
请注意,这完全基于对您的开发环境、目标体系结构等的假设。您所观察到的确切机制可能很有趣 — 但重要的是要记住,这都是 未定义行为 的示例。您不应该依赖它,因为在不同的系统或不同的日期,结果可能会完全不同。
这是我的代码
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] = '[=10=]'; // 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
自
char string[] = "hello";
printf("%s", string);
工作得很好,我不明白为什么 printf("%s", myArray);
不工作,只显示一个 *
。 do/while 循环按预期显示 8 *
,这意味着我的数组已按预期填充。
编辑:如评论中所述,简化了我的示例并尝试了一些解决方案和其他一些可能性。
如果testCharacter初始化为0
我认为你应该为 displayedSecretWord
使用字符指针类型
然后为displayedSecretWord分配sizeof(char) * (characterCount+1)。
我认为这是问题所在。
int *myArray = NULL;
...
printf("%s", myArray);
您正在尝试打印一个整数数组,就好像它是一个字符串一样。我认为,通过将错误类型的变量传递给 printf()
,您将调用 未定义的行为。同样有问题的是,您只为 wordSize+1
字节 分配了足够的内存,然后继续将值写入数组,就好像它足够大 wordSize+1
整数.
通过更改 myArray
的定义来解决此问题:
char *myArray = NULL;
访问此数组成员的其余代码现在应该从写入 int
值更改为写入 char
值。需要明确的是,我认为您不需要更改任何内容。一旦 myArray
被正确定义为 char
.
预计到达时间: 更多关于原始代码中发生的事情。
最初,您分配了 9 个字节。这足以 space 用于略多于 2 个整数(假设 sizeof(int)
是 4)。我还假设这个内存最初是用零填充的。
分配给 myArray
的内存看起来像这样:
myArray[0] 00 00 00 00
myArray[1] 00 00 00 00
myArray[2] 00
然后你遍历并在内存中存储 8 个'*'字符,这使得内存看起来像这样:
myArray[0] '*' 00 00 00
myArray[1] '*' 00 00 00
myArray[2] '*'
请注意,另外五个星号已写入您不拥有的内存中。
然后写入“终止零”,再次写入分配给 myArray
.
然后,你将 myArray
——也就是说,myArray
中第一个字节的地址——传递给 printf()
。您使用了 %s
格式说明符,因此它将打印一个字符串。在打印第一个字节(星号)后,它看到的下一个字节是零,因此它停止了。
最后,您可以访问 myArray
的各个整数成员,就好像它是一个由八个整数组成的数组(即使没有足够的内存容纳三个整数)。这意味着,代码将对应于 myArray[0]
的四个字节读入一个临时整数,并将其值打印为一个字符(因为 %c
格式说明符传递给 printf()
).随着循环的继续,后面的内存区域将被读取,包括不属于您的内存。观察到的结果是星号还在你写的地方。
请注意,这完全基于对您的开发环境、目标体系结构等的假设。您所观察到的确切机制可能很有趣 — 但重要的是要记住,这都是 未定义行为 的示例。您不应该依赖它,因为在不同的系统或不同的日期,结果可能会完全不同。