I have this code and I run it and get his error :
error: array type has incomplete element type 'struct entry'
and I try it to solve it and explore same error but got fail
#ifndef GLOBAL_H
#define GLOBAL_H
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>
//list of CONSTANTS
#define BSIZE 128
#define NONE -1
#define EOS '\0'
#define NUM 256
#define DIV 257
#define MOD 258
#define ID 259
#define DONE 260
//list of prototype function
void init();
int lexan();
int lookup(char s[]);
int insert(char s[], int tok);
void emit(int t,int tval);
void parse();
void expr();
void term();
void factor();
void match(int t);
void error(char* m);
//list of variables
FILE *input, *output, *err;
int tokenval;
int lineno;
int lookahead;
extern struct entry symtable[];
struct entry {
char *lexptr;
int token;
};
#endif
and I get error in this line :
extern struct entry symtable[];
this is code for ( global.h ) and other file not get an error
Move the struct entry definition to be placed before it is first used.
struct entry {
char *lexptr;
int token;
};
extern struct entry symtable[];
I'm developing a library and I would like to know some data about the caller of one of the functions I'm offering. In particular, I would need to know the file name, function name and line where my function (a redefined malloc) is being called.
EDIT: Here's a minimum working example where I can detect when a user calls malloc and "redirect" him to my own malloc function:
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "myLib.h"
int main(){
printf("Inside main, asking for memory\n");
int *p = malloc(sizeof(int));
*p = 3;
free(p);
return 0;
}
myLib.c:
#include "myLib.h"
void * myAlloc (size_t size){
void * p = NULL;
fprintf(stderr, "Inside my own malloc\n");
p = (malloc)(size);
return p;
}
#undef malloc
#define malloc(size) myAlloc(size)
myLib.h:
#ifndef MYLIB_H
#define MYLIB_H
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define malloc(size) myAlloc(size)
void * myAlloc(size_t size);
#endif
I've tried using _FILE_ _func_ and _LINE_ keywords, but I can't make it work since it's in a different module.
You could:
//mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#include <stdlib.h>
// replace malloc in case it's already a macro
#ifdef malloc
#undef malloc
#endif
// I believe that from the standards point of view, this is undefined behavior
#define malloc(size) my_alloc(size, __FILE__, __LINE__, __func__)
#ifdef __GNUC__
// Allow compiler to do static checking.
__attribute__((__alloc_size__(1), __malloc__))
#endif
void *my_alloc(size_t size, const char *file, int line, const char *func);
// ^^^^^^^^ I do not like camelCase case - one snake case to rule them all.
#endif
// mylib.c
#include "mylib.h" // do not ever mix uppercase and lowercase in filenames
#undef malloc // undef malloc so we don't call ourselves recursively
#include <stdio.h>
void *my_alloc(size_t size, const char *file, int line, const char *func){
fprintf(stderr, "Och my god, you wouldn't believe it!\n"
"A function %s in file %s at line %d called malloc!\n",
func, file, line);
return malloc(size);
}
You might also see how assert does it. If you are aiming at glibc, read glibc docs replacing malloc.
Still as you discovered a user may do (malloc)(size) cicumvent macro expansion. You could do:
void *my_alloc(size_t size, const char *file, int line, const char *func);
static inline void *MY_ALLOC(size_t size) {
return my_alloc(size, NULL, 0, NULL);
}
#define MY_ALLOC(size) my_alloc(size, __FILE__, __LINE__, __func__)
// if called with `malloc()` then MY_ALLOC is expanded
// if called as `(malloc)`, then just expands to MY_ALLOC.
#define malloc MY_ALLOC
int main() {
malloc(10); // calls my_alloc(10, "main.c", 62, "main");
(malloc)(20); // calls my_alloc(20, NULL, 0, NULL);
}
GLIBC defines hidden symbols for malloc(), free()... which are called __libc_malloc(), __libc_free()...
So, you can tremendously simplify your debug macros.
In m.h, just define the following:
#if DEBUG_LEVEL > 0
extern void *__libc_malloc (size_t bytes);
extern void *myMalloc(size_t size, const char *filename, const char *funcname, int line);
#define malloc(size) myMalloc(size, __FILE__, __FUNCTION__, __LINE__)
#endif
Then you can write a program defining myMalloc() as follow (e.g. file name is m.c):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "m.h"
#if DEBUG_LEVEL > 0
void *myMalloc(
size_t size,
const char *filename,
const char *funcname,
int line
) {
fprintf(stderr, "malloc(%zu) called from %s/%s()#%d\n", size, filename, funcname, line);
return __libc_malloc(size);
}
#endif
char *dup_str(char *string) {
char *str = malloc(strlen(string) + 1);
strcpy(str, string);
return str;
}
int main(int ac, char *av[]) {
char *str;
if (av[1]) {
str = dup_str(av[1]);
} else {
str = dup_str("NULL");
}
printf("String = '%s'\n", str);
free(str);
return 0;
}
When you compile this example program in non debug mode:
$ gcc m.c -DDEBUG_LEVEL=0
$ ./a.out azerty
String = 'azerty'
When you compile your program in debug mode:
$ gcc m.c -DDEBUG_LEVEL=1
$ ./a.out azerty
malloc(7) called from m.c/dup_str()#27
String = 'azerty'
header bs.h
#ifndef BS_H
#define BS_H
extern int glob_1;
#endif
header og.h
#ifndef OG_H
#define OG_H
#include < bs.h >
extern void func_1( void );
#endif
func_1
#include < og.h >
extern void func_1( void )
{
int dummy;
dummy = 22;
glob_1 += dummy;
}
mainfile
#include < bs.h >
#include < og.h >
int glob_1;
int main()
{
glob_1 = 33;
func_1();
return 0;
}
I have made a small sample that is structured as i understand how to
declare, define init and share globals among different modules.
But this throws me a lnk2019 error - unresolved symbol glob 1
What is wrong here?
I'm trying to define a struct in a header file with function prototypes that take pointer to that struct as a parameter.
#ifndef _GETDATA
#define _GETDATA
struct PERSONDATA{
char name[20];
double age,mass;
};
typedef struct PERSONDATA person;
extern void getData(person *);
extern void getName(char *,int);
#endif
The getData.c file is defined as such;
#include <stdio.h>
void getData(person *ptr)
{
printf("Enter name: ");
getName(ptr->name,sizeof(ptr->name));
}
and the getName.c file is defined as:
#include <stdio.h>
void getName(char *ptrName, int varSize)
{
int i=0;
do
{
*(ptrName++) = getchar();
++i;
if(i==varSize) printf("array full, EXITING!\n");
}while(*(ptrName-1)!='\n' && i<varSize);
}
Lastly, the main function was:
#include <stdio.h>
#include "GETDATA.h"
int main(int argc, char **argv)
{
person human1;
printf("hello, world!\n\n");
getData(&human1);
return 0;
}
On compiling the program, I get the following error:
***C:/Users/Shoaib.Shoaib-PC/Google Drive/C workspace/C workspace codelite/StructPointerExample/getData.c:2:14: error: unknown type name 'person',
void getData(person *ptr)***
Could some one please help me out here, any help is greatly appreciated!
You should include the header file in ALL files using the declared types, not just in the main file.
I need several global pointers to be shared among a few files - the pointers are essentially arrays of double whose lengths are only determined at runtime.
I include here the pieces of the code that caused the issue. This is not the exact code, but it illustrates all the points precisely:
foo.h
#ifndef FOOH
#define FOOH
/* ------------------
COMMON VARIABLES
---------------------*/
// create_bundles.c
extern double *all_bundle;
/* ------------------
COMMON FUNCTIONS
---------------------*/
// create_bundles.c
void create_bundles(int num_firm);
// memory_allocation.c
void allocate_memory(int num_firm, int num_bundle);
void clean_memory(void);
#endif
create_bundles.c
#include "foo.h"
extern double *all_bundle;
void create_bundles(int num_firm) {
int i;
for (i = 0; i < num_firm; i++) {
all_bundle[i] = 1
}
memory_allocation.c
#include "foo.h"
// create_bundles.c
double *all_bundle = NULL;
void allocate_memory(int num_firm, int num_bundle) {
all_bundle = calloc(num_bundle * num_firm, sizeof(double));
}
void clean_memory(void) {
free(all_bundle);
}
main.c
#include "foo.h"
void main(int num_firm, int num_bundle) {
allocate_memory(num_firm, num_bundle);
create_bundles(num_firm);
clean_memory();
}
What happened is that if I print out all_bundle[i] it'll all be 0, and then it'll give me a segmentation error.
Why the error and how to fix it?
The problem is not in global pointer, but something else. Keep looking for the problem in your common code. I hope you are trying to print contents of all_bundle array before calling clean_memory. I have edited your code a little bit and it works great without any segmentation errors and prints 1.0000. Here it is, take a look:
foo.h:
#ifndef FOOH
#define FOOH
// create_bundles.c
extern double *all_bundle;
// create_bundles.c
void create_bundles(int num_firm);
// memory_allocation.c
void allocate_memory(int num_firm, int num_bundle);
void clean_memory(void);
#endif
memory_allocation.c:
#include <stdlib.h>
#include "foo.h"
double *all_bundle = 0;
void allocate_memory(int num_firm, int num_bundle) {
all_bundle = calloc(num_bundle * num_firm, sizeof(double));
}
void clean_memory(void) {
free(all_bundle);
}
create_bundles.c:
#include "foo.h"
void create_bundles(int num_firm) {
int i;
for (i = 0; i < num_firm; i++) {
all_bundle[i] = 1;
}
}
main.c:
#include <stdio.h>
#include "foo.h"
int main(int argc, char *argv[]) {
allocate_memory(100, 1);
create_bundles(100);
{
int i;
for(i = 0; i < 100; ++i)
printf("%f\n", all_bundle[i]);
}
clean_memory();
return 0;
}
Have a header file to access the memory (i.e. add stuff to it, remove stuff from it, readf bits of it, etc).
Have the corresponding .c (or .cpp if that fancies you) to do the magic. And then use static to define the memory.
This is a simple and easy solution to your problem and also enables you to change the implementation if it is required to do so.