访问 struct 中的 char 数组显示越界错误
Accessing char array inside struct showing out of bounds error
我有以下 C 结构并使用函数 getPerson(void)
returns 一个指向我的结构的指针 returns 一个指向使用用户输入的新结构的指针。以下代码无法编译并出现以下错误:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[50];
int age;
} person;
person* getPerson(void)
{
person* newPerson = (person*)malloc(sizeof(person));
int ageInput;
char *nameInputPtr = (char*)malloc(50 * sizeof(char));
printf("Please enter your name: \n");
scanf("%s", nameInputPtr);
printf("Please enter your age: \n");
scanf("%d", &ageInput);
newPerson->name[50] = *nameInputPtr;
newPerson->age = ageInput;
return newPerson;
}
我得到的错误:
struct.c:22:2: error: array index 50 is past the end of the array (which contains 50 elements)
[-Werror,-Warray-bounds]
newPerson->name[50] = *nameInputPtr;
^ ~~
struct.c:6:2: note: array 'name' declared here
char name[50];
^
我设法通过第 22 行中的以下更改修复了我的错误:
22 newPerson->name[49] = *nameInputPtr;
所以我的更改是将第 50 号更改为第 6 行索引定义范围内的第 49 号。
因此,我不明白为什么第 6 行和第 22 行在我的原始代码中给出错误,我想对错误以及我的解决方案的清晰度和功能进行解释。
你必须使用sprintf
strcpy(newPerson->name, nameInputPtr);
注意 C
中的数组是基于 0
的, name[50]
不存在。
在您使用数组作为字符串的特定情况下,您必须验证数组的大小是否为 STR_LEN_MAX+1
,因为字符串以 null 结尾。这意味着字符串中的最后一个字符后始终需要一个字节,其中可以插入 '[=16=]'
个字符。
C
中的数组索引基于 0
。对于分配了 50 字节内存的数组,
char name[50];
尝试使用 [50]
作为索引 off-by-one 并调用 undefined behaviour.
也就是说,
newPerson->name[50] = *nameInputPtr;
不是您复制字符串的方式。你需要利用strcpy()
,比如
strcpy(newPerson->name, nameInputPtr);
另外,在使用 scanf()
时限制输入字符串的长度是一个很好的做法,以避免可能的缓冲区溢出。变化
scanf("%s", nameInputPtr);
到
scanf("%49s", nameInputPtr);
但是,请记住,如果您的设计已经采用 固定大小 分配,那么使用动态内存就没有多大意义。您可以轻松地使用编译时分配的数组。
什么?
这个:
newPerson->name[50] = *nameInputPtr;
说 "assign the character at *nameInputPtr
to the character at index 50 in name
"。但是 name
只有 50 个字符长,并且数组在 C 中是从 0 开始的,所以这是越界的。
不过,该代码没有任何意义!你想要:
strcpy(newPerson->name, nameInputPtr);
复制整个字符串。但是,由于您不限制 scanf()
中的输入,因此存在传播缓冲区溢出的风险。
所以,更好,因为你已经有一个 person
,只需输入它:
scanf("%49s", person->name);
记得检查 return 值。
当然你应该为年龄做同样的事情,不需要一个单独的整数然后复制到结构中。
我有以下 C 结构并使用函数 getPerson(void)
returns 一个指向我的结构的指针 returns 一个指向使用用户输入的新结构的指针。以下代码无法编译并出现以下错误:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[50];
int age;
} person;
person* getPerson(void)
{
person* newPerson = (person*)malloc(sizeof(person));
int ageInput;
char *nameInputPtr = (char*)malloc(50 * sizeof(char));
printf("Please enter your name: \n");
scanf("%s", nameInputPtr);
printf("Please enter your age: \n");
scanf("%d", &ageInput);
newPerson->name[50] = *nameInputPtr;
newPerson->age = ageInput;
return newPerson;
}
我得到的错误:
struct.c:22:2: error: array index 50 is past the end of the array (which contains 50 elements)
[-Werror,-Warray-bounds]
newPerson->name[50] = *nameInputPtr;
^ ~~
struct.c:6:2: note: array 'name' declared here
char name[50];
^
我设法通过第 22 行中的以下更改修复了我的错误:
22 newPerson->name[49] = *nameInputPtr;
所以我的更改是将第 50 号更改为第 6 行索引定义范围内的第 49 号。
因此,我不明白为什么第 6 行和第 22 行在我的原始代码中给出错误,我想对错误以及我的解决方案的清晰度和功能进行解释。
你必须使用sprintf
strcpy(newPerson->name, nameInputPtr);
注意 C
中的数组是基于 0
的, name[50]
不存在。
在您使用数组作为字符串的特定情况下,您必须验证数组的大小是否为 STR_LEN_MAX+1
,因为字符串以 null 结尾。这意味着字符串中的最后一个字符后始终需要一个字节,其中可以插入 '[=16=]'
个字符。
C
中的数组索引基于 0
。对于分配了 50 字节内存的数组,
char name[50];
尝试使用 [50]
作为索引 off-by-one 并调用 undefined behaviour.
也就是说,
newPerson->name[50] = *nameInputPtr;
不是您复制字符串的方式。你需要利用strcpy()
,比如
strcpy(newPerson->name, nameInputPtr);
另外,在使用 scanf()
时限制输入字符串的长度是一个很好的做法,以避免可能的缓冲区溢出。变化
scanf("%s", nameInputPtr);
到
scanf("%49s", nameInputPtr);
但是,请记住,如果您的设计已经采用 固定大小 分配,那么使用动态内存就没有多大意义。您可以轻松地使用编译时分配的数组。
什么?
这个:
newPerson->name[50] = *nameInputPtr;
说 "assign the character at *nameInputPtr
to the character at index 50 in name
"。但是 name
只有 50 个字符长,并且数组在 C 中是从 0 开始的,所以这是越界的。
不过,该代码没有任何意义!你想要:
strcpy(newPerson->name, nameInputPtr);
复制整个字符串。但是,由于您不限制 scanf()
中的输入,因此存在传播缓冲区溢出的风险。
所以,更好,因为你已经有一个 person
,只需输入它:
scanf("%49s", person->name);
记得检查 return 值。
当然你应该为年龄做同样的事情,不需要一个单独的整数然后复制到结构中。