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)

我有下面的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;  
   }
我通过第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