簡體   English   中英

訪問結構內部的char數組,顯示超出范圍的錯誤

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

我有以下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數組索引基於0 對於分配了50字節內存的陣列,

 char name[50];

嘗試使用[50]作為索引是不合一的,並調用未定義的行為

那就是

 newPerson->name[50] = *nameInputPtr;

不是您復制字符串的方式。 您需要使用strcpy() ,例如

strcpy(newPerson->name, nameInputPtr);

另外,在使用scanf()時限制輸入字符串的長度也是一種很好的做法,以避免可能的緩沖區溢出。 更改

scanf("%s", nameInputPtr);

scanf("%49s", nameInputPtr);

但是,請記住,如果您已經具有固定大小分配的設計,那么使用動態內存沒有什么意義。 您可以使用編譯時分配的數組輕松進行更改。

什么?

這個:

newPerson->name[50] = *nameInputPtr;

說“將*nameInputPtr處的字符分配給name中索引50處的字符”。 但是name只有50個字符長,並且數組在C中是從0開始的,所以這是超出范圍的。

但是,該代碼沒有任何意義! 你要:

strcpy(newPerson->name, nameInputPtr);

復制整個字符串。 但是,由於您沒有限制scanf()的輸入,因此存在傳播緩沖區溢出的風險。

因此,更好的是,由於您已經有一個person ,只需輸入:

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

請記住檢查返回值。

當然,您應該對年齡做同樣的事情,不需要一個單獨的整數,然后將其復制到結構中。

您必須使用sprintf

strcpy(newPerson->name, nameInputPtr);

請注意, C中的數組基於0 ,因此name[50]不存在。

在特定情況下,您將數組用作字符串,您必須驗證數組的大小為STR_LEN_MAX+1 ,因為字符串以null結尾。 這意味着字符串始終需要在字符串的最后一個字符之后需要一個字節,可以在其中插入'\\0'字符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM