C 访问结构内部的字符数组显示越界错误
我有下面的C结构,使用返回指向我的结构的指针的函数C 访问结构内部的字符数组显示越界错误,c,arrays,struct,malloc,dynamic-memory-allocation,C,Arrays,Struct,Malloc,Dynamic Memory Allocation,我有下面的C结构,使用返回指向我的结构的指针的函数getPerson(void),使用用户输入返回指向新结构的指针。以下代码未编译,并出现以下错误: #include <stdio.h> #include <stdlib.h> typedef struct { char name[50]; int age; } person; person* getPerson(void)
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;
}
我通过第22行中的以下更改来修复我的错误:
22 newPerson->name[49] = *nameInputPtr;
所以我的改变是将数字50改为数字49,在第6行的索引定义的范围内
因此,我不明白为什么第6行和第22行在我的原始代码中会出现错误,我想对错误以及我的解决方案的清晰度和功能性进行解释 您必须使用
sprintf
strcpy(newPerson->name, nameInputPtr);
请注意,C
中的数组是基于0
的,因此名称[50]
不存在
在使用数组作为字符串的特定情况下,必须验证数组的大小是否为
STR_LEN_MAX+1
,因为字符串以null结尾。这意味着字符串中的最后一个字符后面总是需要一个字节,可以插入'\0'
字符。您必须使用sprintf
strcpy(newPerson->name, nameInputPtr);
请注意,C
中的数组是基于0
的,因此名称[50]
不存在
在使用数组作为字符串的特定情况下,必须验证数组的大小是否为
STR_LEN_MAX+1
,因为字符串以null结尾。这意味着字符串中的最后一个字符后面总是需要一个字节,可以插入'\0'
字符。C中的数组索引基于0
。对于已分配50字节内存的阵列
char name[50];
尝试使用[50]
,因为索引关闭了1并调用
也就是说
newPerson->name[50] = *nameInputPtr;
不是复制字符串的方式。你需要利用,比如
另外,在使用scanf()
时限制输入字符串长度是一种很好的做法,以避免可能的缓冲区溢出。改变
scanf("%s", nameInputPtr);
到
但是,请记住,如果您已经有了固定大小分配的设计,那么使用动态内存没有多大意义。您可以轻松地使用编译时分配的数组进行更改。
C
中的数组索引基于0
。对于已分配50字节内存的阵列
char name[50];
尝试使用[50]
,因为索引关闭了1并调用
也就是说
newPerson->name[50] = *nameInputPtr;
不是复制字符串的方式。你需要利用,比如
另外,在使用scanf()
时限制输入字符串长度是一种很好的做法,以避免可能的缓冲区溢出。改变
scanf("%s", nameInputPtr);
到
但是,请记住,如果您已经有了固定大小分配的设计,那么使用动态内存没有多大意义。您可以轻松地使用编译时分配的数组进行更改。什么
这:
表示“将*nameInputPtr
处的字符分配给name
中索引50处的字符”。但是name
只有50个字符长,而且数组在C中是基于0的,所以这是不允许的
尽管如此,这些代码还是毫无意义!你想要:
strcpy(newPerson->name, nameInputPtr);
复制整个字符串。但是,由于您没有在scanf()
中限制输入,因此这有传播缓冲区溢出的风险
因此,更好的是,因为您已经有了一个人
,只需输入:
scanf("%49s", person->name);
记住检查返回值
当然,你也应该对年龄做同样的处理,不需要一个单独的整数,然后复制到结构中。什么
这:
表示“将*nameInputPtr
处的字符分配给name
中索引50处的字符”。但是name
只有50个字符长,而且数组在C中是基于0的,所以这是不允许的
尽管如此,这些代码还是毫无意义!你想要:
strcpy(newPerson->name, nameInputPtr);
复制整个字符串。但是,由于您没有在scanf()
中限制输入,因此这有传播缓冲区溢出的风险
因此,更好的是,因为您已经有了一个人
,只需输入:
scanf("%49s", person->name);
记住检查返回值
当然,对于年龄也应该这样做,不需要一个单独的整数,然后将其复制到结构中。C数组从零开始索引,因此数组[50]中的最后一个有效索引是49。类似地,数组[10]有十个有效索引:0123456789。大多数编程语言中的数组都是0索引的,因此边界中的索引将介于0和n-1之间。
malloc()
的返回值,如@unwind.:-)通过直接读取newPerson
的字段,您可以大大简化代码,并且在调用scanf()时,不必使用两个临时变量ageInput
和nameInputPtr
1),始终检查返回值(而不是参数值),以确保操作成功。2) 使用“%s”允许用户使接收缓冲区溢出。建议使用scanf(“%49s”,nameInputPtr);'其中“49”比输入缓冲区的长度小一个,因为scanf将在%s输入中附加“\0”字符。(注意,除了建议的方法外,还有其他方法可以指定%s输入的最大长度)C数组从零开始索引,因此数组[50]中的最后一个有效索引是49。类似地,数组[10]有十个有效索引:0123456789。大多数编程语言中的数组都是0索引的,因此边界中的索引将介于0和n-1之间。malloc()
的返回值,如@unwind.:-)通过直接读取newPerson
的字段,您可以大大简化代码,并且在调用scanf()时,不必使用两个临时变量ageInput
和nameInputPtr
1),始终检查返回值(而不是参数值),以确保操作成功。2) 使用“%s”允许用户使接收缓冲区溢出。建议使用scanf(“%49s”,nameInputPtr);'其中'49'比输入缓冲区的长度小一个,如sc