【发布时间】:2015-06-05 12:14:22
【问题描述】:
我有以下 C 结构并使用函数 getPerson(void) 返回指向我的结构的指针,使用用户输入返回指向新结构的指针。以下代码无法编译并给出以下错误:
#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 更改为数字 49,使其位于第 6 行的索引定义的范围内。
因此,我不明白为什么第 6 行和第 22 行会在我的原始代码中出现错误,我想解释一下这个错误以及我的解决方案的清晰度和功能。
【问题讨论】:
-
C 数组从零开始索引,因此 array[50] 中的最后一个有效索引是 49。类比而言,array[10] 有十个有效索引:0123456789。
-
大多数编程语言中的数组都是 0 索引的,因此索引范围在 0 到 n-1 之间
-
do not cast
malloc()的返回值,正如@unwind所说。 :-) -
你可以通过直接读入
newPerson的字段来大大简化你的代码,并且没有ageInput和nameInputPtr这两个临时变量 -
1) 调用 scanf() 时始终检查返回值(而不是参数值)以确保操作成功。 2) 使用“%s”允许用户溢出接收缓冲区。建议 'scanf("%49s", nameInputPtr);'其中 '49' 比输入缓冲区的长度小一,因为 scanf 会将 '\0' 字符附加到 %s 输入。 (注意,除了建议的方法之外,还有其他方法可以指定 %s 输入的最大长度)
标签: c arrays struct malloc dynamic-memory-allocation