I am trying to run the program below where one contains a date and the other contains the clothes in an outfit. The date structure works fine, but the one about the outfit results in the following error:
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
I have followed other questions and realized I must put an '&' in each string copy to make sure strings can be inputted, but I cannot find what is causing the error above. My code is seen below:
//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;
}
I am trying to print out a string that mentions clothes worn, as shown in the program. However, I get the error listed above.
EDIT: I have removed the '&' symbols, but now I get the errors below:
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)
| ~~~~~~~~~~~~~~~~~^~~~~~
Looking specifically at the warning, &wtywtd.Face[100]
is a pointer to one element past the end of the wtywtd.Face
, so you're telling strcpy
to write to memory after the given array. Writing past the bounds of a variable's memory triggers undefined behavior which in your case manifests in a crash.
You want to pass the starting address of the array to strcpy
, i.e.:
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");
Note that an array when used in an expression decays to a pointer to its first member.