gcc 4.4.4 c89
I am keep getting a "Cannot dereference to incomplete type".
However, I am sure I have my structure type complete. I return the Network_t instance that is the pointer to the allocated memory. I should be able to dereference that memory.
Many thanks for any advice,
I have this in my header file:
driver.h
typedef struct Network_t Network_t;
Network_t* create_network(int id);
Implementation file
driver.c
#include "driver.h"
struct Network_t {
int id;
};
Network_t* create_network(int id)
{
Network_t *network = malloc(sizeof *network);
if(network) {
network->id = id;
}
return network;
}
And in my main.c
#include "driver.h"
Network_t *network = NULL;
network = create_network(1);
printf("Network ID: [ %d ]\n", network->id); /* Cannot dereference pointer to incomplete type */
From main.c you only have a forward declaration of struct Network_t visible. To access id from a pointer to struct Network_t you need a definition of the struct to be visible at the point at which you dereference it.
You could move the definition from driver.c to driver.h.
this one works
in driver.h
#include <stdio.h>
#include<stdlib.h>
struct Network_t{
int id;
};
Network_t *create_network( int id){
Network_t *network=(Network_t *)malloc(sizeof(network));
if (network){
network->id=id;
}
return network;
}
in Network.cpp
#include <iostream>
#include "driver.h"
using namespace std;
int main(){
Network_t *network=NULL;
network=create_network(1);
printf("Network ID:[%d]\n",network->id);
return 0;
}
result:
Network ID:[1]
Related
Checked couple of stack overflow questions/answers but none correspond to what I am trying to do. Here is it:
I have a c object file myobject.c containing struct type populated at run time (as initialised by main file having the main() function. Below is the skeletal structure of myobject.c:
typedef struct
{
uint16_t ID;
float tempo;
char unit[10];
unsigned long timestamp;
} prv_data_t;
static uint8_t prv_value(lwm2m_data_t* dataP,
prv_data_t* tempData)
{
uint8_t ret = COAP_205_CONTENT;
//TO DO here
.
.
.
return ret;
}
static uint8_t prv_read(..paramList)
{
//TO DO here
.
.
//then call prv_value here
result = prv_value((*tlvArrayP)+i, tempData);
return result;
}
object_t * get_object(){
//this func get called by main.c to initialize myobject
}
Skeletal structure of the main.cfile:
myFunc(mypar p) {
}
main(){
//initialize myobject
//.....
//access myobject struct member here, pass to myFunc call
myFunc(tempo)
}
The main.c initialises myobject.c. Now I want to access tempo a member of prv_data_tfrom myobject.cfor some computation. How do I achieve such a task without exposing prv_data_t in main.c?
EDIT: here's what I mean by main.c initialises myobject.c and all other objects, please:
/*
* Now the main function fill an array with each object,
* Those functions are located in their respective object file.
*/
objArray[0] = get_security_object();
if (NULL == objArray[0])
{
fprintf(stderr, "Failed to create security object\r\n");
return -1;
}
.
.
.
The main file actually contains the main()function.
You can avoid exposing your private data by doing:
Let main work with pointers to incomplete type struct prv_data_t
Implement getter-functions (and setter-functions) for members that you allow main to access
Something like this:
a.h
#include <stdio.h>
struct prv_data_t; // Incomplete type
struct prv_data_t * get_obj();
float get_tempo(struct prv_data_t * this);
a.c
#include <stdio.h>
#include <stdlib.h>
struct prv_data_t
{
int ID;
float tempo;
char unit[10];
unsigned long timestamp;
};
float get_tempo(struct prv_data_t * this)
{
return this->tempo;
}
struct prv_data_t * get_obj()
{
struct prv_data_t * p = malloc(sizeof *p);
p->tempo = 42.0;
return p;
}
main.c
#include <stdio.h>
#include "a.h"
int main()
{
struct prv_data_t * p = get_obj();
printf("%f\n", get_tempo(p));
// The line below can't compile because the type is incomplete
// printf("%f\n", p->tempo);
return 0;
}
So with this kind of code main only knows that there exists a struct prv_data_t but main knows nothing about the members of that struct.
I am trying to create my own malloc function, and I did not finished yet. Here is related part of my code:
mymalloc.h :
#pragma once
#include <stdlib.h>
typedef struct METADATA{
struct METADATA *next;
struct METADATA *prev;
int free;
size_t size;
}METADATA;
METADATA *metadata;
void *mm_malloc(size_t size);
mymalloc.c
#include "mm_alloc.h"
#include "stdlib.h"
#include "stdio.h"
void *mm_malloc(size_t size) {
if(size == 0)
return NULL;
METADATA *tmp;
long address;
if(metadata == NULL){
sbrk(sizeof(tmp));
sbrk(size);
address = sbrk(0);
return (void *)address;
}
}
In the sbrk(sizeof(tmp)); part of mymalloc.c, I got "Implicit declaration of function sbrk()". What I wanted to do ise creating a place for metadata of new block and also a place for the required size. Where am I doing wrong?
Add the line
#include <unistd.h>
At the top of the file 'mymalloc.c' so that the function is declared
I am trying to send a structure array as reference, but for some reason I cannot get it to work, as value it is able to pass it but not as reference (&)
This is my code:
#include <stdio.h>
#include <string.h>
struct mystruct {
char line[10];
};
void func(struct mystruct record[])
{
printf ("YES, there is a record like %s\n", record[0].line);
}
int main()
{
struct mystruct record[1];
strcpy(record[0].line,"TEST0");
func(record);
return 0;
}
I thought that only by calling the function func(&record) and changing the func function arguments as "struct mystruct *record[]" it was going to work... but it didn't.
Any help please.
I think you've got your pointers and references concepts mixed up.
func(&record) would pass the address of the variable record and not a reference.
passing pointers
#include <stdio.h>
#include <string.h>
struct mystruct {
char line[10];
};
void func(struct mystruct * record)
{
printf ("YES, there is a record like %s\n", record[0].line);
// OR
printf ("YES, there is a record like %s\n", record->line);
}
int main()
{
struct mystruct record[1];
strcpy(record[0].line,"TEST0");
func(record); // or func(&record[0])
return 0;
}
if you must pass a reference, try this
#include <stdio.h>
#include <string.h>
struct mystruct {
char line[10];
};
void func(struct mystruct & record)
{
printf ("YES, there is a record like %s\n", record.line);
}
int main()
{
struct mystruct record[1];
strcpy(record[0].line,"TEST0");
func(record[0]);
return 0;
}
Update
To address the comment(s) below,
references are not available in pure C, available only in C++
the 'fault' in the original code was a struct mystruct record[] should have been struct mystruct & record
I am trying to declare a struct and use it in multiple files and I am getting an error that I cannot figure out. Sample code is posted below.
in test.h
#ifndef TEST_H
#define TEST_H
struct mystruct;
struct mystruct *new_mystruct();
void myprint(struct mystruct*,int);
#endif
int test.c
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
struct mystruct {
int *myarray;
};
struct mystruct *new_mystruct(int length)
{
int i;
struct mystruct *s;
s = malloc(sizeof(struct mystruct));
s->myarray = malloc(length*sizeof(int));
for(i = 0; i < length; ++i)
s->myarray = 2*i;
return s;
}
in main.c
#include "test.h"
#include <stdio.h>
int main()
{
int len = 10;
struct mystruct *c = new_mystruct(len);
myprint(c, len);
printf("%f", c->myarray[3]); // error: dereferencing pointer to incomplete type
return 0;
myprint() prints out 0 2 4 6 8 10 12 14 16 18. why doesn't the myprint(function work but the printf statement doesn't? why is it ok to pass it into a function but not use it in main? Thanks.
Currently main() only knows that struct mystruct is a type, but it doesn't know anything about its internal structure, because you've hidden it in test.c.
So you need to move this definition:
struct mystruct {
int *myarray;
};
from test.c to test.h, so that it's visible to main().
Note: what you're doing here is a classic example of an opaque type. This can be a very useful technique when you want to hide implementation details from code that is going to be calling your API.
Main.c doesn't know the contents of the mystruct structure. Try moving these lines:
struct mystruct {
int *myarray;
};
from test.c to test.h.
While you're at it, I think you mean "int myarray" not "int *myarray".
I have 2 header files api.h and impl.h
api.h is visible to outside files and will be included in other ".c" files. So api.h includes impl.h
api.h defines 2 structures
typedef struct
{
uint32_t att;
union
{
struct
{
void* buffer;
size_t length;
} x;
struct
{
int a, b;
} v;
} content;
}dummy;
and impl.h has some other structures and function def which uses this structure.
I tried forward declaration but it doesn't help me .
Please help .
Actually, your dummy is not a structure, but a typedef to an unnamed structure. Try naming the structure, you can then forward-declare it:
typedef struct sdummy dummy; // forward declaration
void foo(dummy *);
struct sdummy { ... }; // definition
Either reorder your code in api.h so the type declaration precedes the #include "impl.h" or give your (currently anonymous) structure itself a name like dummy, dummy_, dummy_s so you can add a forward declaration
typedef struct dummy_ dummy;
to impl.h.
If you want to hide the details of your struct then you have to define it in some .c file, let's say impl.c, so that it has internal linkage to that compilation unit. To use it you have to expose create, destroy, getter and setter functions. So a basic setup would look like this:
api.h with forward declaration for your struct
// forward declaration
typedef struct dummy* dummy_t;
// create / destroy / setter / getter (omitted)
dummy_t alloc_dummy();
void free_dummy(dummy_t);
void set_number(dummy_t, int);
void set_string(dummy_t, char*);
void print_dummy(dummy_t);
Then comes impl.c
#include "api.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct dummy {
int n;
char* s;
};
dummy_t alloc_dummy()
{
return malloc(sizeof(struct dummy));
}
void free_dummy(dummy_t dummy)
{
if(dummy) {
free(dummy->s);
free(dummy);
}
}
void set_number(dummy_t dummy, int n)
{
if(dummy) {
dummy->n = n;
}
}
void set_string(dummy_t dummy, char* s)
{
if(dummy && s) {
dummy->s = strdup(s);
}
}
void print_dummy(dummy_t dummy)
{
if(dummy) {
printf("%d, %s\n", dummy->n, dummy->s);
}
}
And finally the usage in some other C files, here main.c
#include "api.h"
int main(int argc, char** argv)
{
// struct dummy d; // error! type is unknown
// instead use the create function
dummy_t d = alloc_dummy();
// d->n = 1; // error! dereference of unknown type
// instead use the setter function
set_number(d, 1);
set_string(d, "Hello, world!");
print_dummy(d);
free_dummy(d);
return 0;
}
Ouput
1, Hello, world!