简体   繁体   English

访问结构内部的char数组,显示超出范围的错误

[英]Accessing char array inside struct showing out of bounds error

I have the following C struct and using the function getPerson(void) that returns a pointer to my struct returns a pointer to a new struct using user input. 我有以下C结构,并使用函数getPerson(void)返回指向我的结构的指针,并使用用户输入返回指向新结构的指针。 The following code does not compile and it gives the following error: 以下代码无法编译,并产生以下错误:

     #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;  
   }

Error I get: 错误我得到:

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];
    ^

I manage to fix my error by the following change in the line 22: 我设法通过在第22行进行以下更改来修复错误:

22  newPerson->name[49] = *nameInputPtr;

So my change was to change number 50, to number 49 to be inside the bounds of the index definition of line 6. 所以我的更改是将数字50更改为数字49,使其位于第6行的索引定义的范围内。

Therefore I don't understand why line 6 and line 22 give an error in my original code and I would like to have an explanation about the error and on the clarity and functionality of my solution to this. 因此,我不明白为什么第6行和第22行在我的原始代码中出现错误,并且我想对错误以及我对此解决方案的清晰度和功能性进行解释。

Array index in C is 0 based. C数组索引基于0 For an array with 50 bytes of memory allocated, 对于分配了50字节内存的阵列,

 char name[50];

trying to use [50] as index is off-by-one and invokes undefined behaviour . 尝试使用[50]作为索引是不合一的,并调用未定义的行为

That said, 那就是

 newPerson->name[50] = *nameInputPtr;

is not the way you copy a string. 不是您复制字符串的方式。 You need to make use of strcpy() , like 您需要使用strcpy() ,例如

strcpy(newPerson->name, nameInputPtr);

Also, it is a good practice to limit the input string length while using scanf() to avoid possible buffer overrun. 另外,在使用scanf()时限制输入字符串的长度也是一种很好的做法,以避免可能的缓冲区溢出。 Change 更改

scanf("%s", nameInputPtr);

to

scanf("%49s", nameInputPtr);

However, please keep in mind, there is not much point in using dynamic memory if you already have a design with fixed-sized allocation. 但是,请记住,如果您已经具有固定大小分配的设计,那么使用动态内存没有什么意义。 You can vary easily make use of a compile-time allocated array. 您可以使用编译时分配的数组轻松进行更改。

What? 什么?

This: 这个:

newPerson->name[50] = *nameInputPtr;

says "assign the character at *nameInputPtr to the character at index 50 in name ". 说“将*nameInputPtr处的字符分配给name中索引50处的字符”。 But name is only 50 characters long, and arrays are 0-based in C so this is out of bounds. 但是name只有50个字符长,并且数组在C中是从0开始的,所以这是超出范围的。

Still, that code doesn't make any sense! 但是,该代码没有任何意义! You want: 你要:

strcpy(newPerson->name, nameInputPtr);

to copy the entire string. 复制整个字符串。 This runs the risk of propagating a buffer overrun since you don't limit the input in scanf() , though. 但是,由于您没有限制scanf()的输入,因此存在传播缓冲区溢出的风险。

So, better, since you already have a person , just input into it: 因此,更好的是,由于您已经有一个person ,只需输入:

scanf("%49s", person->name);

Remember to check the return value. 请记住检查返回值。

Of course you should do the same for the age, no need for a separate integer which is then copied into the structure. 当然,您应该对年龄做同样的事情,不需要一个单独的整数,然后将其复制到结构中。

You have to use sprintf 您必须使用sprintf

strcpy(newPerson->name, nameInputPtr);

Take note that arrays in C are 0 based, the name[50] does not exist. 请注意, C中的数组基于0 ,因此name[50]不存在。

In your specific case you are using array as string, the you must verify that the size of your array is STR_LEN_MAX+1 , because of strings are null terminated. 在特定情况下,您将数组用作字符串,您必须验证数组的大小为STR_LEN_MAX+1 ,因为字符串以null结尾。 That means strings always need a byte after last char in your string where a '\\0' char can be inserted. 这意味着字符串始终需要在字符串的最后一个字符之后需要一个字节,可以在其中插入'\\0'字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM