为什么在数组中添加空字符?
Why null chars added in array?
我有一个数组,它保留 字符串 的 chars 并想找到它的 suffixes.如果我在数组中添加 7 个字符,则字符总数应为 7*8/2 = 28。因此 suffix_array 限制应为 28。当我尝试创建后缀数组时,我注意到该数组有空字符 ass出色地。所以我的输出是错误的。 这是什么原因?
#include <stdio.h>
#include <stdlib.h>
static char *suffix;
int main()
{
char s[7] = {'c','o','n','n','e','c','t'};
suffix = (char*) malloc(sizeof (char)*28);
int j;
static int k=0;
j=k;
for(int i=0; i<28; i++) {
suffix[i] = s[j];
printf("%c ", suffix[i]);
if(j<7) {
j++;
}
else {
k++;
j=k;
}
}
return 0;
}
Output:
c o n n e c t o n n e c t n n e c t n e c t e c
您最终得到 j==7 (if (j<7) { j++; }
),这超出了 s
。
替换
if(j<7) {
j++;
}
else {
k++;
j=k;
}
和
j++;
if(j==7) {
k++;
j=k;
}
提示:
硬编码 7 和 28 是个坏主意(包括 Vlad 的做法)。最好使用
char s[] = {...}; size_t n = sizeof(s)/sizeof(s[0]);
(如果是数组)
const char *s = "connect"; size_t n = strlen(s);
(如果是字符串)
你并没有真正使用suffix
。但是,如果您想在 suffix
中构建一个字符串,请确保为尾随 NUL 再分配一个字符并添加尾随 NUL!
for 循环即使在其第一次迭代中也会调用未定义的行为
for(int i=0; i<28; i++) {
suffix[i] = s[j];
printf("%c ", suffix[i]);
if(j<7) {
j++;
}
//...
当j
等于6
时增加
if(j<7) {
j++;
}
所以j
等于7
并且这个值在赋值语句
循环的下一次迭代中使用
suffix[i] = s[j];
因此,可以访问数组 s
的最后一个元素之后的内存,因为该数组的有效索引范围是 [0, 7 )
.
注意在文件作用域声明变量后缀,使局部变量静态化,意义不大。
您的程序至少可以按以下方式简化
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
enum { N = 7, M = ( N * ( N + 1 ) ) / 2 };
const char s[N] = { 'c','o','n','n','e','c','t' };
char *suffix = malloc( sizeof( char ) * M );
for ( size_t i = 0, k = 0, j = k; i < M; i++ )
{
suffix[i] = s[j++];
printf("%c ", suffix[i]);
if ( j == N ) j = ++k;
}
free( suffix );
return 0;
}
程序输出为
c o n n e c t o n n e c t n n e c t n e c t e c t c t t
请注意,当不再需要动态分配的数组时,您应该始终释放它们。
实际上在这个程序中不需要动态分配结果数组。你可以只写
char suffix[M];
我有一个数组,它保留 字符串 的 chars 并想找到它的 suffixes.如果我在数组中添加 7 个字符,则字符总数应为 7*8/2 = 28。因此 suffix_array 限制应为 28。当我尝试创建后缀数组时,我注意到该数组有空字符 ass出色地。所以我的输出是错误的。 这是什么原因?
#include <stdio.h>
#include <stdlib.h>
static char *suffix;
int main()
{
char s[7] = {'c','o','n','n','e','c','t'};
suffix = (char*) malloc(sizeof (char)*28);
int j;
static int k=0;
j=k;
for(int i=0; i<28; i++) {
suffix[i] = s[j];
printf("%c ", suffix[i]);
if(j<7) {
j++;
}
else {
k++;
j=k;
}
}
return 0;
}
Output:
c o n n e c t o n n e c t n n e c t n e c t e c
您最终得到 j==7 (if (j<7) { j++; }
),这超出了 s
。
替换
if(j<7) {
j++;
}
else {
k++;
j=k;
}
和
j++;
if(j==7) {
k++;
j=k;
}
提示:
硬编码 7 和 28 是个坏主意(包括 Vlad 的做法)。最好使用
char s[] = {...}; size_t n = sizeof(s)/sizeof(s[0]);
(如果是数组)const char *s = "connect"; size_t n = strlen(s);
(如果是字符串)你并没有真正使用
suffix
。但是,如果您想在suffix
中构建一个字符串,请确保为尾随 NUL 再分配一个字符并添加尾随 NUL!
for 循环即使在其第一次迭代中也会调用未定义的行为
for(int i=0; i<28; i++) {
suffix[i] = s[j];
printf("%c ", suffix[i]);
if(j<7) {
j++;
}
//...
当j
等于6
时增加
if(j<7) {
j++;
}
所以j
等于7
并且这个值在赋值语句
suffix[i] = s[j];
因此,可以访问数组 s
的最后一个元素之后的内存,因为该数组的有效索引范围是 [0, 7 )
.
注意在文件作用域声明变量后缀,使局部变量静态化,意义不大。
您的程序至少可以按以下方式简化
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
enum { N = 7, M = ( N * ( N + 1 ) ) / 2 };
const char s[N] = { 'c','o','n','n','e','c','t' };
char *suffix = malloc( sizeof( char ) * M );
for ( size_t i = 0, k = 0, j = k; i < M; i++ )
{
suffix[i] = s[j++];
printf("%c ", suffix[i]);
if ( j == N ) j = ++k;
}
free( suffix );
return 0;
}
程序输出为
c o n n e c t o n n e c t n n e c t n e c t e c t c t t
请注意,当不再需要动态分配的数组时,您应该始终释放它们。
实际上在这个程序中不需要动态分配结果数组。你可以只写
char suffix[M];