如何修复C语言结构体中strcpy引发的栈溢出及参数类型错误?
C结构体穿搭字符串复制错误修复
问题现象
运行包含日期与穿搭结构体的C程序,日期功能正常,但穿搭部分出现栈溢出错误,尝试添加/移除&符号后仍无法解决。
初始错误信息
main.c: In function ‘main’: main.c:41:5: warning: ‘__builtin_memcpy’ writing 21 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=] 41 | strcpy(&wtywtd.Face[100], "Prescription_Glasses"); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main.c:34:19: note: at offset 500 into destination object ‘wtywtd’ of size 500 34 | struct Outfit wtywtd; | ^~~~~~ Todays date is 5/7/2016 *** stack smashing detected ***: terminated
初始代码
//Reviewing structures #include <stdio.h> #include <string.h> int main() { //The following is a structure for a date. //A structure can be defined as a group of variables struct date //Here, a structure called 'data', along with inner variable like the month, the date, and the year are displayed { int month; int day; int year; }; //A variable must be declared to link the structure: struct date DateToday; //The following below shows how to assign values to inside the structure: DateToday.month = 5; DateToday.day = 7; DateToday.year = 2016; struct Outfit { char Footwear[100]; char Bottoms[100]; char Tops[100]; char OverTop[100]; char Face[100]; }; struct Outfit wtywtd; //When declaring strings, you must use double quotes strcpy(&wtywtd.Footwear[100], "Dark_Black_and_Gray_Nike_shoes"); strcpy(&wtywtd.Bottoms[100], "Dark_Beige_Cargo_Shorts"); strcpy(&wtywtd.Tops[100], "Dark_Red_And_Black_Striped_Tshirt"); strcpy(&wtywtd.OverTop[100], "Grey_Hooded_Fleece_Jacket"); strcpy(&wtywtd.Face[100], "Prescription_Glasses"); printf("Todays date is %i/%i/%i", DateToday.month,DateToday.day,DateToday.year); printf("\nThe clothes I wore when going out were %s, %s, %s, %s, and %s", wtywtd.Footwear, wtywtd.Bottoms, wtywtd.Tops, wtywtd.OverTop, wtywtd.Face); return 0; }
移除&后的错误信息
main.c: In function ‘main’: main.c:37:27: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion] 37 | strcpy(wtywtd.Footwear[100], "Dark_Black_and_Gray_Nike_shoes"); | ~~~~~~~~~~~~~~~^~~~~ | | | char In file included from main.c:3: /usr/include/string.h:141:39: note: expected ‘char * restrict’ but argument is of type ‘char’ 141 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src) | ~~~~~~~~~~~~~~~~~^~~~~~ main.c:38:26: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion] 38 | strcpy(wtywtd.Bottoms[100], "Dark_Beige_Cargo_Shorts"); | ~~~~~~~~~~~~~~^~~~~ | | | char In file included from main.c:3: /usr/include/string.h:141:39: note: expected ‘char * restrict’ but argument is of type ‘char’ 141 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src) | ~~~~~~~~~~~~~~~~~^~~~~~ main.c:39:23: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion] 39 | strcpy(wtywtd.Tops[100], "Dark_Red_And_Black_Striped_Tshirt"); | ~~~~~~~~~~~^~~~~ | | | char In file included from main.c:3: /usr/include/string.h:141:39: note: expected ‘char * restrict’ but argument is of type ‘char’ 141 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src) | ~~~~~~~~~~~~~~~~~^~~~~~ main.c:40:26: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion] 40 | strcpy(wtywtd.OverTop[100], "Grey_Hooded_Fleece_Jacket"); | ~~~~~~~~~~~~~~^~~~~ | | | char In file included from main.c:3: /usr/include/string.h:141:39: note: expected ‘char * restrict’ but argument is of type ‘char’ 141 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src) | ~~~~~~~~~~~~~~~~~^~~~~~ main.c:41:23: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion] 41 | strcpy(wtywtd.Face[100], "Prescription_Glasses"); | ~~~~~~~~~~~^~~~~ | | | char In file included from main.c:3: /usr/include/string.h:141:39: note: expected ‘char * restrict’ but argument is of type ‘char’ 141 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src) | ~~~~~~~~~~~~~~~~~^~~~~~
问题根源
- 初始写法错误:
&wtywtd.Footwear[100]是取数组第101个元素的地址(数组下标从0开始,Footwear[100]已经超出数组0-99的合法范围),直接越界写入到结构体的其他内存区域,触发栈溢出。 - 移除
&后的错误:wtywtd.Footwear[100]是取数组越界位置的单个char值,而strcpy要求第一个参数是char*类型的指针,因此出现类型不匹配警告。
修复方案
直接传递数组名作为strcpy的第一个参数——数组名本身就是指向数组首元素的指针,符合strcpy对char*类型参数的要求。
修正后的代码
//Reviewing structures #include <stdio.h> #include <string.h> int main() { struct date { int month; int day; int year; }; struct date DateToday; DateToday.month = 5; DateToday.day = 7; DateToday.year = 2016; struct Outfit { char Footwear[100]; char Bottoms[100]; char Tops[100]; char OverTop[100]; char Face[100]; }; struct Outfit wtywtd; // 直接使用数组名作为strcpy的目标指针 strcpy(wtywtd.Footwear, "Dark_Black_and_Gray_Nike_shoes"); strcpy(wtywtd.Bottoms, "Dark_Beige_Cargo_Shorts"); strcpy(wtywtd.Tops, "Dark_Red_And_Black_Striped_Tshirt"); strcpy(wtywtd.OverTop, "Grey_Hooded_Fleece_Jacket"); strcpy(wtywtd.Face, "Prescription_Glasses"); printf("Todays date is %i/%i/%i", DateToday.month,DateToday.day,DateToday.year); printf("\nThe clothes I wore when going out were %s, %s, %s, %s, and %s", wtywtd.Footwear, wtywtd.Bottoms, wtywtd.Tops, wtywtd.OverTop, wtywtd.Face); return 0; }
内容的提问来源于stack exchange,提问作者Jason Beswilan
相关产品推荐
相关产品推荐

