Initialization of multidimensional pointers with different dimensional anonym arrays inline - c

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

Related

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.

2D array passing in C

How can I create an array so that I can pass it as a pointer to this function?
void SomeFunction(double *a, double *b, double *c);
I made my 2d arrays like so (but I have errors):
static double matrix_a [MATRIX_DIM][MATRIX_DIM];
static double matrix_b [MATRIX_DIM][MATRIX_DIM];
static double matrix_c [MATRIX_DIM][MATRIX_DIM];
for (i=0;i<MATRIX_DIM;i++) {
for (j=0;j<MATRIX_DIM;j++) {
// initializing matrices here
}
}
Now I make pointers to the arrays:
double *a = &matrix_a;
double *b = &matrix_b;
double *c = &matrix_c;
And then call the function:
SomeFunction(a, b, c);
However I get the following error:
cannons.c: In function ‘main’:
cannons.c:29:14: warning: initialization from incompatible pointer type [enabled by default]
double *a = &matrix_a;
^
cannons.c:30:14: warning: initialization from incompatible pointer type [enabled by default]
double *b = &matrix_b;
^
cannons.c:31:14: warning: initialization from incompatible pointer type [enabled by default]
double *c = &matrix_c;
^
Why ?
double * means "pointer to a single double". However you have an array whose elements are arrays of double. So you in fact want a pointer to an array of double:
double (*a)[MATRIX_DIM] = &matrix_a[0]; // or matrix_a
when you access it as a[1][2] = 5.0;. Alternatively you could point to the entire array at once:
double (*x)[MATRIX_DIM][MATRIX_DIM] = &matrix_a;
but then you need an extra level of indirection to access it: (*x)[1][2] = 5.0;
You will need to use the same declaration in the parameter list too.

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)).

variable-sized object may not be initialized

So this section of code generates a huge amount of errors but it works when I have InputM[3][3] = blah
Why would this be. For reference, code:
int n = 3;
printf("%ld\n", n);
double InputM[n][n] = { { 2, 0, 1 }, { 3, 1, 2 }, { 5, 2, 5} };
Generates:
prog3.c: In function 'main':
prog3.c:47: error: variable-sized object may not be initialized
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM[0]')
prog3.c:47: warning: excess elements in array initializer
prog3.c:47: warning: (near initialization for 'InputM')
Compile-time, you compiler does not know how many elements are in your matrix. In C, you can dynamically allocate memory using malloc.
You could use a define to create a constant value:
#define N 3
int main()
{
double InputM[N][N] = { { 2, 0, 1 }, { 3, 1, 2 }, { 5, 2, 5} };
}
Or malloc:
int main()
{
int n = 3;
int idx;
int row;
int col;
double **inputM;
inputM = malloc(n * sizeof(double *));
for (idx = 0; idx != n; ++idx)
{
inputM[idx] = malloc(n * sizeof(double));
}
// initialise all entries on 0
for (row = 0; row != n; ++row)
{
for (row = 0; row != n; ++row)
{
inputM[row][col] = 0;
}
}
// add some entries
inputM[0][0] = 2;
inputM[1][1] = 1;
inputM[2][0] = 5;
}
In C99, variable-sized array can't be initialized, why ?
Because at the compile time, the compiler doesn't know the exact size of array, so you cannot initialize it.
n will be evaluated at runtime, then your array will be allocated on the stack-frame.

Resources