Parsing a Simple Expression Statement - c

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.

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.

invalid operands to binary - (have 'int *' and 'int **')

#include<stdio.h>
void main()
{
int a[]= {10,20,30,40,50,60};
int *p[]= {a,a+1,a+2,a+3,a+4,a+5};
int **pp=p;
pp++;
printf("%d,%d,%d", pp-p,*pp-a, **pp);
*pp++;
printf("%d,%d,%d", pp-p, *pp-p, *pp-p);
++*pp;
printf("%d,%d,%d", pp-p, *pp-a, **pp);
++**pp;
printf("%d,%d,%d", pp-p, *pp-a, **pp);
}
it's showing this error:
invalid operands to binary - (have 'int *' and 'int **')
printf("%d,%d,%d", pp-p, *pp-p, *pp-p);
invalid operands to binary - (have 'int *' and 'int **')
printf("%d,%d,%d", pp-p, *pp-p, *pp-p);
*pp-p, you cannot subtract a int** from an int* since they are not compatible types. It should be pp-p.
Also please note that in order to print addresses with printf, you should cast the pointers to void* and print using %p.

Initialization of multidimensional pointers with different dimensional anonym arrays inline

I am having a noob problem.
I am making tetris in c.
I want to initialize a double pointer in a struct inline for every instance.
The width of the array differs, but it is defined in another variable.
Code:
typedef struct {
char height, width;
char **shape;
} Shape;
const Shape S_shape = {2,3, (char [][3]){{0,1,1},{1,1,0}}};
const Shape Z_shape = {2,3, (char [][3]){{1,1,0},{0,1,1}}};
const Shape T_shape = {2,3, (char [][3]){{0,1,0},{1,1,1}}};
const Shape L_shape = {2,3, (char [][3]){{0,0,1},{1,1,1}}};
const Shape ML_shape = {2,3, (char [][3]){{1,0,0},{1,1,1}}};
const Shape SQ_shape = {2,2, (char [][2]){{1,1},{1,1}}};
const Shape R_shape = {1,4, (char [][4]){{1,1,1,1}}};
int main() {
return 0;
}
It does not work. Here is the gcc error code:
tetris.c:11:1: warning: initialization from incompatible pointer type [enabled by default]
const Shape S_shape = {2,3, (char [][3]){{0,1,1},{1,1,0}}};
^
tetris.c:11:1: warning: (near initialization for ‘S_shape.shape’) [enabled by default]
tetris.c:12:1: warning: initialization from incompatible pointer type [enabled by default]
const Shape Z_shape = {2,3, (char [][3]){{1,1,0},{0,1,1}}};
^
tetris.c:12:1: warning: (near initialization for ‘Z_shape.shape’) [enabled by default]
tetris.c:13:1: warning: initialization from incompatible pointer type [enabled by default]
const Shape T_shape = {2,3, (char [][3]){{0,1,0},{1,1,1}}};
^
tetris.c:13:1: warning: (near initialization for ‘T_shape.shape’) [enabled by default]
tetris.c:14:1: warning: initialization from incompatible pointer type [enabled by default]
const Shape L_shape = {2,3, (char [][3]){{0,0,1},{1,1,1}}};
^
tetris.c:14:1: warning: (near initialization for ‘L_shape.shape’) [enabled by default]
tetris.c:15:1: warning: initialization from incompatible pointer type [enabled by default]
const Shape ML_shape = {2,3, (char [][3]){{1,0,0},{1,1,1}}};
^
tetris.c:15:1: warning: (near initialization for ‘ML_shape.shape’) [enabled by default]
tetris.c:16:1: warning: initialization from incompatible pointer type [enabled by default]
const Shape SQ_shape = {2,2, (char [][2]){{1,1},{1,1}}};
^
tetris.c:16:1: warning: (near initialization for ‘SQ_shape.shape’) [enabled by default]
tetris.c:17:1: warning: initialization from incompatible pointer type [enabled by default]
const Shape R_shape = {1,4, (char [][4]){{1,1,1,1}}};
^
tetris.c:17:1: warning: (near initialization for ‘R_shape.shape’) [enabled by default]
Gcc: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
Thanks!
SOLVED
https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html
You're missing some compound literals and using the wrong type in the one you're using. Here is a small example of what you might want:
const Shape S_shape = {
2, /* height */
2, /* width */
(char *[]) { /* Compound literals, declaring an anonymous array of `char *` with static storage duration */
(char []) {0, 1}, /* Another compound literal, declaring a static storage duration for a `char []` that will be pointed by `char *[]` */
(char []) {1, 1} /* Same as above, this one the next (and last) element of `char *[]` */
}
};
Without the comments (for readability):
const Shape S_shape = {
2,
2,
(char *[]) {
(char []) {0, 1},
(char []) {1, 1}
}
};
https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html

Trouble Understanding C Basics

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)

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