Impossible to use malloc and typedef - c

It seems that it is impossible to use typedef and incorporate a malloc function in my program: More specifically:
groups.h
#include "headers.h"
#include "info.h"
#include "sub_list.h"
typedef struct group_entity *group;
group new_group(int id);
void free_group(group group);
groups.c
#include "groups.h"
struct group_entity {
int gId;
info gFirst;
info gLast;
subinfo gSub;
};
group new_group(int id) {
group new_group = malloc(sizeof(group));
if (!new_group) {
return NULL;
}
new_group->gId = id;
new_group->gFirst = NULL;
new_group->gLast = NULL;
new_group->gSub = NULL;
return new_group;
}
void free_group(group group) {
free(group);
}
header.h
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#define MG 5 /* Length of Groups Array. */
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include "headers.h"
#include "groups.h"
#include "info.h"
#include "sub_list.h"
int main() {
group new_object = new_group(5);
return 0;
}
Whenever I run this piece of code, I get halted with a breakpoint
exe_common.inl - ln 297.
if (!has_cctor)
_cexit();
I've tried using a free_group(group group) function in my main.c - but it seems that I hit a breakpoint.
By using the VS 2019 debugger, I tried to find out which line causes the error. It seems that the breakpoint is caused AFTER my main is executed.
Quite curious behavior, since main won't even return 0.

Typedef pointers are confusing. sizeof(group) is the size of the pointer not the size of the data. Consider using a typedef to the data, and adding * everywhere you are using a pointer, to indicate, clearly, that you are working with pointers.
typedef struct group_entity group;
group *new_group(int id);
void free_group(group *group);
group *new_group(int id) {
group *new_group = malloc(sizeof(group));
Alternatively, you can do sizeof(*new_group) or sizeof(struct group_entity).

In addition to what KamilCuk said here, I would say that you can use a define directive in your groups.h file if your intent was to avoid to specify the * everytime.
typedef struct group_entity group;
#define *group GROUP_PTR
GROUP_PTR new_group(int id);
Then in your groups.c replace with the following:
GROUP_PTR new_group(int id) {
GROUP_PTR new_group = malloc(sizeof(group));
[...]
return new_group;
}
It should work like a charm.

Related

why can't i access the pointer to a structure from another file and get the members

this a reproducible example and not the entire code the entire code is too large..
my problem was that i had a structure that i created using malloc and i needed to access it from another function in another file, but i keep getting segfault...
header file
main.h
#ifndef main_a
#define main_a
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct cmd_s
{
int n;
} cmd_t;
extern cmd_t *ptr;
void push(char *line);
#endif
the main.c file
main.c
#include "main.h"
cmd_t *ptr = NULL;
int main(void)
{
cmd_t *ptr = malloc(sizeof(cmd_t));
ptr->n = 5;
push("line");
return (0);
}
and where i need to access the struct from named opcode.c
opcode.c
#include "main.h"
void push(char *line)
{
int new = ptr->n;
}
note that this is not the actual code the actual code has useful values, this is an example that contains the challenge i am facing
i tried to use static instead but i got the same error.
i'm still a novice in c programming..
and i don't want to change the way i created the structure, which is through malloc because another function depends on it... i just need to make that malloced structure accessible to another file in the program.
thanks.
int main(void)
{
cmd_t *ptr = malloc(sizeof(cmd_t));
You create new ptr variable visible only in function main. Your push see the global pointer ptr but not the one you have malloced.
You need to
int main(void)
{
ptr = malloc(sizeof(*ptr));
/* .... */
Use obiects not types in sizeof (as in this example)

I am questioning how this code compiled even though struct iwreq does not have ifr_name as a member

I wrote very simple code using struct iwreq.
Also, I expected this will be error.
But it is compiled and works.
I looked inside linux/wireless.h which has the definition of struct iwreq.
And the iwreq does not ifr_name as a member.
Would someone can give me an idea?
Here is the simple code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/wireless.h>
int main(void)
{
char *intf = "eth0";
struct iwreq iwr;
strncpy(iwr.ifr_name, intf, sizeof(iwr.ifr_name));
printf("main : intf = %s, iwr.ifr_name = %s\n", intf, iwr.ifr_name);
return 0;
}
wireless.h includes if.h, and inside if.h you can find:
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
So the code is translated to:
strncpy(iwr.ifr_ifrn.ifrn_name, intf, sizeof(iwr.ifr_ifrn.ifrn_name));
/usr/include/linux/wireless.h includes linux/if.h:
#include <linux/if.h> /* for IFNAMSIZ and co... */
And in /usr/include/linux/if.h there is:
#define ifr_name ifr_ifrn.ifrn_name /* interface name */

what's the difference between pointer==null and !pointer in my code?

in extended_map.c I wrote:
#include "extended_map.h"
#include "map.h"
#include <stdlib.h>
struct Extended_Map_t{
char* key;
};
Extended_Map extended_mapCreate()
{
Extended_Map extended_map = malloc(sizeof(*extended_map));
if (!extended_map)
{
return NULL;//Here is the problem
}
return NULL;
}
in extended_map.h I wrote:
typedef struct Extended_Map_t* Extended_Map;
But Clion shows me the the first return NULL which is located inside if statement is not reachable. why is that?
Note: I think I didn't have this issue before updating to the newset version of Clion which was released today, Plus changing !extended_map to extended_map==NULL solves the issues...

sys/queue.h error: request for member in something not a structure or union (TAILQ)

I'm building a small file utility that relies on queues and I've been getting the error on compile:
error: request for member "entries" in something not a structure or union
I stripped it down to just the queue handling lines, and I'm getting the same error, here's the source for the header:
#ifndef _tailq_test_h
#define _tailq_test_h
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/queue.h>
struct tail_q {
TAILQ_ENTRY(tail_q) entries;
int item;
};
TAILQ_HEAD(tail_queue, tail_q);
static struct tail_queue queue;
int main();
#endif
And for the program:
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/queue.h>
#include "tailq-test.h"
static struct tail_queue queue;
int main()
{
struct tail_q *q_ptr;
int data = 1;
TAILQ_INIT(&queue);
TAILQ_INSERT_HEAD(&queue, &data, entries);
return 0;
}
The traceback refers to the line TAILQ_INSERT_HEAD(&queue, &data, entries);, it has the same effect if TAILQ_INSERT_TAIL is used instead.
I'm not sure why it's not compiling. I checked the answer from this question and the provided example compiled just fine. I'm having trouble spotting the difference/what I'm doing wrong.
Any help would be much appreciated.
I wasn't too familiar with TAILQ, so I took a look at the source code that you can find here : http://www.gnu.org/software/mifluz/doc/doxydoc/queue_8h-source.html
Here is the source code for TAILQ_INSERT_HEAD :
#define TAILQ_INSERT_HEAD(head, elm, field) do {
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)
(head)->tqh_first->field.tqe_prev =
&(elm)->field.tqe_next;
As you can see, the second parameter elm needs to be a struct containing the third parameter as a member (field).
In your situation, your second parameter is an int *, which does not have an entries member as pointed out by your error message.
From my understanding, you must pass a tail_q struct as your second parameter for your code to compile.
EDIT :
For example, the following code compiles :
int main()
{
struct tail_q q;
int data = 1;
q.item = data; // Include your data in your struct.
TAILQ_INIT(&queue);
TAILQ_INSERT_HEAD(&queue, &q, entries); // Notice that I am passing a tail_q pointer here.
return 0;
}

Storing a global struct variable inside another global struct in C

I’m trying to figure out a way to use nested global structs as a sort of API namespacing for my C library.
Specifically, I want to expose a single Primary ‘namespacing struct,’ that contains other such structs (such as Primary.Secondary), that themselves contain function pointers (Primary.Secondary.a_function()).
I’ve abstracted out the following (relatively) simple example of what I want to do:
main.c:
#include "Primary.h"
int main () {
Primary.Secondary.a_function();
return 0;
}
Primary.h:
#if !defined(SECONDARY_H)
# include "Secondary.h"
#endif
struct Primary_struct {
struct Primary__Secondary_struct Secondary;
} extern Primary;
Primary.c:
#include "Primary.h"
struct Primary_struct Primary = {
.Secondary = Primary__Secondary
};
Secondary.h:
struct Primary__Secondary_struct {
void (*a_function) (void);
void (*another_function) (void);
} extern Primary__Secondary;
Secondary.c:
#include "Secondary.h"
#include <stdio.h>
void Primary__Secondary__a_function (void);
void Primary__Secondary__another_function (void);
struct Primary__Secondary_struct {
.a_function = Primary__Secondary__a_function,
.another_function = Primary__Secondary__another_function
} extern Primary__Secondary;
void Primary__Secondary__a_function(void) {
Primary.Secondary.another_function();
}
void Primary__Secondary__another_function(void) {
printf("run!\n");
}
When I attempt to compile this, I run into the following compiler error:
> C -O0 Primary.c Secondary.c main.c
Primary.c:3:33: error: initializer element is not a compile-time constant
struct Primary_struct Primary = {
^
1 diagnostic generated.
I should note, ideally, both the Primary and Primary__Secondary variables would be const. I was worried that the added complexity would exacerbate the problem… so for now, I’ve left that aspect out.
The problem seems to be that, for some reason, even when set as const, and containing only elements present at compile time, the Primary__Secondary struct is not a compile-time constant, and thus cannot be stored in another struct at compile-time. I can probably work around this by setting up all of the interfaces at runtime, but… that seems like a really hacky solution. I’m looking for any alternative solutions to this problem, that the more C-fu of you than I can come up with.
(Note: This is related to this question, but is substantially different, and quite a bit more specific.)
What you're trying can't be done; sorry. Here's a condensed example:
#include <stdio.h>
int a = 5;
int b = a;
int main(int argc, char *argv[])
{
printf("Hello, world!\n");
return 0;
}
Compiling this code gives the error:
main.c:4: error: initializer element is not constant
Because the compiler doesn't know how to make the assignment int b = a at compile time. It's just the way the language works!
You had some odd notations in your code - I've converted them to a more orthodox form. Also, as a general rule, avoid using double-underscore in names; in C++ this is absolutely necessary.
You also need to use a pointer to the embedded structure - then the code will run:
Primary.h
//Primary.h:
#ifndef PRIMARY_H
#define PRIMARY_H
#include "Secondary.h"
struct Primary_struct {
struct Primary_Secondary_struct *Secondary;
};
extern struct Primary_struct Primary;
#endif // PRIMARY_H
Secondary.h
//Secondary.h:
#ifndef SECONDARY_H
#define SECONDARY_H
struct Primary_Secondary_struct {
void (*a_function)(void);
void (*another_function)(void);
};
extern struct Primary_Secondary_struct Primary_Secondary;
#endif // SECONDARY_H
Primary.c
//Primary.c:
#include "Primary.h"
struct Primary_struct Primary = {
.Secondary = &Primary_Secondary
};
Secondary.c
//Secondary.c:
#include "Secondary.h"
#include "Primary.h"
#include <stdio.h>
void Primary_Secondary_a_function(void);
void Primary_Secondary_another_function(void);
struct Primary_Secondary_struct Primary_Secondary = {
.a_function = Primary_Secondary_a_function,
.another_function = Primary_Secondary_another_function
};
void Primary_Secondary_a_function(void) {
Primary_Secondary.another_function();
printf("hide!\n");
}
void Primary_Secondary_another_function(void) {
printf("run!\n");
}
main.c
//main.c:
#include "Primary.h"
int main () {
Primary.Secondary->a_function();
return 0;
}
This generates:
run!
hide!
I ended up going with a runtime approach, at least for now. I might try a pointers approach (suggested by Jonathan Leffler above) later on, and see if I end up with a less complex / more comprehensible codebase… but this works for now.
I use clang (and gcc)’s __attribute__((constructor)) extension to set up the structs’ relationships at runtime; the same could be achieved more portably (but less cleanly) with some code in main().
I’d offer a little more explanation, but it’s 4AM here… heh. I’ve spent all day on this >,<
main.c:
#include "Package.h"
int main () {
Package.One.a_function();
Package.One.another_function();
Package.Two.a_function();
Package.Two.another_function();
return 0;
}
Package.h:
#define PACKAGE_H
#if !defined(ONE_H)
# include "One.h"
#endif
#if !defined(TWO_H)
# include "Two.h"
#endif
// It seems this is broken, at least in `clang`
// #if __has_feature(attribute_constructor)
# define constructor __attribute__((constructor))
// #endif
struct Package_struct {
struct Package__One_struct One;
struct Package__Two_struct Two;
};
struct Package_struct extern Package;
Package.c:
#include "Package.h"
struct Package_struct Package = {};
One.h:
#define ONE_H
struct Package__One_struct {
void (*a_function) (void);
void (*another_function) (void);
};
struct Package__One_struct extern Package__One;
One.c:
#include "One.h"
#include "Package.h"
#include <stdio.h>
void Package__One__a_function (void);
void Package__One__another_function (void);
struct Package__One_struct Package__One = {
.a_function = Package__One__a_function,
.another_function = Package__One__another_function
};
void constructor Package__register_One(void) {
Package.One = Package__One; }
void Package__One__a_function(void) {
Package.One.another_function();
}
void Package__One__another_function(void) {
printf("one!\n");
}
Two.h:
#define TWO_H
struct Package__Two_struct {
void (*a_function) (void);
void (*another_function) (void);
};
struct Package__Two_struct extern Package__Two;
Two.c:
#include "Two.h"
#include "Package.h"
#include <stdio.h>
void Package__Two__a_function (void);
void Package__Two__another_function (void);
struct Package__Two_struct Package__Two = {
.a_function = Package__Two__a_function,
.another_function = Package__Two__another_function
};
void constructor Package__register_Two(void) {
Package.Two = Package__Two; }
void Package__Two__a_function(void) {
Package.Two.another_function();
}
void Package__Two__another_function(void) {
printf("two!\n");
}

Resources