Trouble Understanding C Basics - c

I am attempting to get into C programming, and I am having problems with assigning and pulling data from C-arrays, (in this case, to and from C-style strings).
Please point out any faults you see here.
I am primarily a c++/python programmer, so please keep the explanations of memory usage and management as simple as possible.
#include <stdio.h>
typedef struct AuthorInfo {
char* firstName;
char* lastName;
} AuthorInfo;
typedef struct BookEntry {
char bookID;
char* bookName;
AuthorInfo author;
} BookEntry;
void assign_str(const char** from, char** to) {
int size = sizeof(from)/sizeof(char);
printf((char)size);
printf('\n');
for (int i=0; i < size; i++) {
(*to)[i] = (*from)[i];
};
};
BookEntry BookEntry_(const int id, const char* bName, const char* aF, const char*aL, BookEntry* ret) {
ret->bookID = id;
ret->bookName = (char*)malloc(sizeof(bName));
ret->author.firstName = (char*)malloc(sizeof(aF));
ret->author.lastName = (char*)malloc(sizeof(aL));
assign_str(bName, &ret->bookName);
assign_str(aF, &ret->author.firstName);
assign_str(aL, &ret->author.lastName);
}
void display_book(BookEntry* entry) {
printf(entry->bookName);
printf('\n');
printf(entry->author.firstName);
printf(' ');
printf(entry->author.lastName);
printf('\n');
};
int main(int argc, char** args) {
BookEntry book;
book.bookID = 0;
assign_str("Tom Sawyer", &book.bookName);
assign_str("Mark", &book.author.firstName);
assign_str("Twain", &book.author.lastName);
display_book(&book);
return 0;
};
Compiling this code with gcc goof.c -o goof -std=c11 results in :
goof.c: In function ‘assign_str’:
goof.c:16:10: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [-Wint-conversion]
printf((char)size);
^
In file included from goof.c:1:0:
/usr/include/stdio.h:362:12: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern int printf (const char *__restrict __format, ...);
^
goof.c:16:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf((char)size);
^
goof.c:17:10: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [-Wint-conversion]
printf('\n');
^
In file included from goof.c:1:0:
/usr/include/stdio.h:362:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern int printf (const char *__restrict __format, ...);
^
goof.c:17:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf('\n');
^
goof.c: In function ‘BookEntry_’:
goof.c:25:26: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
ret->bookName = (char*)malloc(sizeof(bName));
^
goof.c:25:26: warning: incompatible implicit declaration of built-in function ‘malloc’
goof.c:25:26: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
goof.c:28:14: warning: passing argument 1 of ‘assign_str’ from incompatible pointer type [-Wincompatible-pointer-types]
assign_str(bName, &ret->bookName);
^
goof.c:14:6: note: expected ‘const char **’ but argument is of type ‘const char *’
void assign_str(const char** from, char** to) {
^
goof.c:29:14: warning: passing argument 1 of ‘assign_str’ from incompatible pointer type [-Wincompatible-pointer-types]
assign_str(aF, &ret->author.firstName);
^
goof.c:14:6: note: expected ‘const char **’ but argument is of type ‘const char *’
void assign_str(const char** from, char** to) {
^
goof.c:30:14: warning: passing argument 1 of ‘assign_str’ from incompatible pointer type [-Wincompatible-pointer-types]
assign_str(aL, &ret->author.lastName);
^
goof.c:14:6: note: expected ‘const char **’ but argument is of type ‘const char *’
void assign_str(const char** from, char** to) {
^
goof.c: In function ‘display_book’:
goof.c:34:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf(entry->bookName);
^
goof.c:35:10: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [-Wint-conversion]
printf('\n');
^
In file included from goof.c:1:0:
/usr/include/stdio.h:362:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern int printf (const char *__restrict __format, ...);
^
goof.c:35:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf('\n');
^
goof.c:36:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf(entry->author.firstName);
^
goof.c:37:10: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [-Wint-conversion]
printf(' ');
^
In file included from goof.c:1:0:
/usr/include/stdio.h:362:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern int printf (const char *__restrict __format, ...);
^
goof.c:37:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf(' ');
^
goof.c:38:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf(entry->author.lastName);
^
goof.c:39:10: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [-Wint-conversion]
printf('\n');
^
In file included from goof.c:1:0:
/usr/include/stdio.h:362:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern int printf (const char *__restrict __format, ...);
^
goof.c:39:3: warning: format not a string literal and no format arguments [-Wformat-security]
printf('\n');
^
goof.c: In function ‘main’:
goof.c:45:14: warning: passing argument 1 of ‘assign_str’ from incompatible pointer type [-Wincompatible-pointer-types]
assign_str("Tom Sawyer", &book.bookName);
^
goof.c:14:6: note: expected ‘const char **’ but argument is of type ‘char *’
void assign_str(const char** from, char** to) {
^
goof.c:46:14: warning: passing argument 1 of ‘assign_str’ from incompatible pointer type [-Wincompatible-pointer-types]
assign_str("Mark", &book.author.firstName);
^
goof.c:14:6: note: expected ‘const char **’ but argument is of type ‘char *’
void assign_str(const char** from, char** to) {
^
goof.c:47:14: warning: passing argument 1 of ‘assign_str’ from incompatible pointer type [-Wincompatible-pointer-types]
assign_str("Twain", &book.author.lastName);
^
goof.c:14:6: note: expected ‘const char **’ but argument is of type ‘char *’
void assign_str(const char** from, char** to) {
^
And running the code causes bash to say:
Segmentation fault (core dumped)

There's many errors in there and no array, only structs.
first, you must include the stdlib library (#include <stdlib.h>)
secondly, the printf function can't be used like that.
This function need a string to know how to print the data ex:printf("an int: %d",myInt); or printf("a string: %s",myString);. Note the %d or %s they indicate where to put the data.
thirdly I think you want this void assign_str(const char* from, char** to)

Related

How can I fix this error which causes my other string not to print?

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.

My compiler returned "assignment to 'int *' from incompatible pointer type 'char *' [-Wincompatible-pointer-types]" when I ran my C program

#include <stdio.h>
int main()
{
char grade = 'A';
int *p = &grade;
printf("The address where the grade is stored: %p\n", p);
printf("Grade: %c\n", grade);
return 0;
}
I get this error each time I compile the code on VScode but never on code blocks.
warning: incompatible pointer types initializing 'int *' with an
expression of type 'char *' [-Wincompatible-pointer-types]
int *p = &grade;
^ ~~~~~~
1 warning generated.
 ./main
The address where the grade is stored: 0x7ffc3bb0ee2b
Grade: A"
The warning tells you exactly what it is. It says:
incompatible pointer types initializing 'int *' with an expression of type 'char *'
This means that p is of type int *, that &grade is of type char *, and that these two pointers are not compatible. The solution is to change the declaration of p to:
char *p = &grade;
One more thing. Usually you can safely do implicit conversions to and from any pointer to void *, but not when passed as argument to a variadic function. If you want to print the address, use this:
printf("%p", (void *)p);
But only cast when needed. Never do it just to get rid of warnings. Here is an answer I wrote about that: https://stackoverflow.com/a/62563330/6699433
As an alternative, you could use a void pointer directly:
void *p = &grade;
printf("%p", p);
But then you would need to cast if you want to dereference it. For example:
char c = *(char*)p;
That cast is not necessary if p is declared as char *.

Parsing a Simple Expression Statement

I am trying to build a parser for arithmetic expression using yacc. I have also included some semantic actions with it. But whenever I run the code it shows segmentation fault(core dumped). Please Help.
This is my yacc file.
%{
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int yylex();
void yyerror(const char *s);
int temp[100];
char var[2]="t0";
char label[2]="L1";
%}
%union
{
struct attributes
{
char code[100];
char addr[100];
char op[2];
}type_id;
char ch;
}
%start L
%token ID NUM WHILE OR AND NOT True False Do end GE LE EE NE UMINUS
%right '='
%left AND OR
%left '<' '>' LE GE NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!'
%type<type_id>L
%type<type_id>E
%type<ch>ID
%type<ch>NUM
%%
%%
#include "lex.yy.c"
int main()
{
printf("Enter the exp: ");
yyparse();
}
This is my Lex file.
alpha [A-Za-z]
digit [0-9]
%%
[ \t\n]
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
. return yytext[0];
%%
When I compile my file I get this:
rome#rome-VirtualBox:~/Desktop/CompDesin$ gcc y.tab.c -ll -ly
test.y: In function ‘yyparse’:
test.y:48:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:49:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:36: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
strcat(temp,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:51:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:52:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:53:52: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:60:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:61:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:62:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:63:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:64:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$$.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:65:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:66:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:67:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"+");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:68:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:69:53: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:74:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:78:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
rome#rome-VirtualBox:~/Desktop/CompDesin$ gcc y.tab.c -ll -ly
test.y: In function ‘yyparse’:
test.y:48:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:49:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:36: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
strcat(temp,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:51:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:52:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:53:52: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:60:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:61:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:62:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:63:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:64:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$$.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:65:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:66:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:67:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"+");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:68:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:69:53: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:74:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:78:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
And when I run my file i get this error:
rome#rome-VirtualBox:~/Desktop/CompDesin$ ./a.out
Enter the exp: a=b+c
Segmentation fault (core dumped)
There are multiple problems:
there are several places where you provoke undefined behaviour.
lexer values are not stored correctly
Two notes:
keep in mind, that strings in C are terminated with a NUL byte and therefore the character arrays need to be dimensioned accordingly
for some of them the compiler warns you, it is a good idea to pay attention to the compiler warnings
Let's go through the different issues quickly:
Like Paul R and bruno noted correctly temp should be char array and the dimensions of var and label arrays are too small
then it still crashes, because ID and NUM are
defined as
%type<ch>ID
%type<ch>NUM
and ch is:
char ch;
in the %union statement.
The crashes occur because you define strcat(temp,$1); on line 50. $1 represents a single character, but your code tries to interpret this as a NUL-terminated string (char * pointer). You have similar cases on lines 74 and 78 with strcpy($$.addr,$1);. As mentioned earlier, the compiler warns you about this. This provokes undefined behavior, which in your case manifests itself in a segmentation error.
You could correct this e.g. to strncat(temp,&$1,1); to use only one character but in comments you write that your number of characters to be copied will differ and will depend on the input.
Therefore change the definition perhaps in %union to something like:
char strval[100];
Then adapt:
%type<strval>ID
%type<strval>NUM
Set the values in the scanner
It would no longer crash now, but it would not work as intended because the values are not set in the scanner. There only the type (ID or NUM) is determined, but the associated value is not set.
There it should look like:
{digit}+ {
strcpy(yylval.strval, yytext);
return NUM;
}
{alpha}({alpha}|{digit})* {
strcpy(yylval.strval, yytext);
return ID;
}
Scanner
You are currently including the "lex.yy.c" file in the .y file, like so:
#include "lex.yy.c"
I would rather do it the other way around. Remove it from there and instead make an include of the yacc generated "y.tab.h" in the .l file. So the beginning of the .l file could look like this:
%{
#include "y.tab.h"
%}
alpha [A-Za-z]
...
The commands for building would be (might differ a little bit on your platform):
flex scanner.l
yacc -d grammar.y
cc -Wall -Wextra y.tab.c lex.yy.c -ll
Finally, an input like
a=bb+c+4711
would produce an output like:
t0=bb+c
t1=t0+4711
Further possible improvements
Once this works as desired, you can either think about dynamically allocating memory for values, as recommended by rici in the comments section, or limit the length of values to ensure that they are not written beyond the end of fixed-size buffers.

Single Linked List that implements push and pop - seg fault

I'm looking over some old code to write a program (in C) that creates push and pop methods similar to a stack for a singly linked list. I'm currently getting a segmentation fault and can't figure out the issue.
The input for any pushes will be single characters, here's an input example:
push ;
push g
push .
pop
push -
Code (commented out some things that were causing errors):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node
{
char data;
struct node* next;
}*top = NULL;
void push(char c);
char pop();
int main(int argc, char *argv[])
{
char* p1;
char p2;
FILE *fp = NULL;
fp = fopen(argv[2], "r");
loop:
while (!feof(fp))
{
fscanf(fp,"%s", &p1);
while (strcmp(&p1,"push") == 0)
{
fscanf(fp,"%s", &p2);
printf("%s\n", &p2);
// push(&p2);
fscanf(fp,"%s", &p1);
if (strcmp(&p1,"pop") == 0)
{
//pop();
fscanf(fp,"%s", &p1);
}
}
while (strcmp(&p1,"pop") == 0)
{
//pop();??
fscanf(fp,"%s",&p1);
if (strcmp(&p1,"push") == 0)
{
fscanf(fp,"%s",&p2);
printf("%s\n",&p2);
// push(&p2);
}
goto loop;
}
}
fclose(fp);
return 0;
}
void push(char c)
{
struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
temp->data = c;
temp->next = top;
top = temp;
}
char pop()
{
struct node *temp = top;
char data = temp->data;
top = top->next;
free(temp);
return data;
}
Current Warnings:
stack.c: In function âmainâ:
stack.c:24:3: warning: format â%sâ expects argument of type âchar *â, but argument 3 has type âchar **â [-Wformat]
stack.c:26:3: warning: passing argument 1 of âstrcmpâ from incompatible pointer type [enabled by default]
/usr/include/string.h:143:12: note: expected âconst char *â but argument is of type âchar **â
stack.c:31:4: warning: format â%sâ expects argument of type âchar *â, but argument 3 has type âchar **â [-Wformat]
stack.c:32:4: warning: passing argument 1 of âstrcmpâ from incompatible pointer type [enabled by default]
/usr/include/string.h:143:12: note: expected âconst char *â but argument is of type âchar **â
stack.c:35:5: warning: format â%sâ expects argument of type âchar *â, but argument 3 has type âchar **â [-Wformat]
stack.c:39:3: warning: passing argument 1 of âstrcmpâ from incompatible pointer type [enabled by default]
/usr/include/string.h:143:12: note: expected âconst char *â but argument is of type âchar **â
stack.c:42:4: warning: format â%sâ expects argument of type âchar *â, but argument 3 has type âchar **â [-Wformat]
stack.c:43:4: warning: passing argument 1 of âstrcmpâ from incompatible pointer type [enabled by default]
/usr/include/string.h:143:12: note: expected âconst char *â but argument is of type âchar **â
The warnings already tell you, what to do. The pointers the functions expect char*, and the pointer you pass &p1 aka char** are of different type. To fix this you must use p1 instead of &p1.
But you have another issue, you use p1 before it is initialized. This leads to segmentation faults too, because the pointer points nowhere and the functions printf or strcmp try to access the content there.
This means in the case of fscanf, you must allocate memory, where the content can be stored, see malloc. Same goes for p2, of course.
first of all p1 hav't any memory to point to. secondly you are passing &p1 to fscanf but fscanf expects it to be char * and &p1 has char ** since you have deplared it to be char *p1 and char *p2.what i ll suggest is you do the coding from scratch instead of coping the code coz this code has many intax errors.and probably your segmentation fault is because of the fscanf() itself coz you are passing argument of wring type.

different declarations of array of pointers

Suppose that I have an array of pointers:
char *names[] = { "Za" , "John"};
Can I declare it like this:(?)
char **names = { "Za" , "John" }
The reason I am trying to do this is that I am trying to increment the array to print its contents such that I can do:
printf("%s \n" , *(++names))
So I can get printf to print "John".
I tried the declaration char **names and I got the following warning upon compilation:
test.c: In function ‘main’:
test.c:6:2: warning: initialization from incompatible pointer type [enabled by default]
char **names = { "Za" , "John"};
^
test.c:6:2: warning: (near initialization for ‘names’) [enabled by default]
test.c:6:2: warning: excess elements in scalar initializer [enabled by default]
test.c:6:2: warning: (near initialization for ‘names’) [enabled by default]
P.S my C file name is test.c
Thanks.
Just do char **pCurrentName = names;, then you'll be able to do printf("%s \n" , *(++pCurrentName)).

Resources