Setting struct variables - C - c

I have some code in the following kind of layout, I believe that the topExample/botExample aren't being set properly when I call addTopBotExample. I think this is due to the top bot variables being on the functions stack and so being cleared when the function ends? I have a feeling that perhaps I need to malloc the memory first, but am not sure how I would go about doing this are even if its the right approach.
typedef struct Example Example;
struct Example {
/* normal variables ...*/
Example *topExample;
Example *botExample;
};
....
void addTopBotExample(Example **example, int someVariable) {
Example top = createTopExample(int someVariable); //(createTopExample returns a
//type Example based on some input)
Example bot = createBotExample(int someVariable);
(*example)->topExample = ⊤
(*example)->botExample = ⊥
return;
}

If createTopExample isn't allocating memory, this is going to cause problems the moment it's called more than once. Rewrite createTopExample and createBotExample to use malloc and return an Example*. Something like this:
Example* createTopExample(stuff)
{
Example *example = malloc(sizeof(Example));
// ... stuff you do
return example;
}
Then your addTopBotExample would look like this:
void addTopBotExample(Example **example, int someVariable) {
if ((*example)->topExample)
free((*example)->topExample)
if ((*example)->botExample)
free((*example)->botExample)
(*example)->topExample = createTopExample(int someVariable);
(*example)->botExample = createBotExample(int someVariable);
return;
}
Note that this addTopBotExample will free the allocated memory before calling malloc again but before your program ends, you need to call free on any lingering Examples that used this addTopBotExample function:
free(exampleInstanceThatWasPassedIntoAddTopBotExampleAtSomePoint.topExample);
free(exampleInstanceThatWasPassedIntoAddTopBotExampleAtSomePoint.botExample);

You have already everything together. Allocate the Example in createTopExample or createTopExample
Example *createTopExample(int someVariable)
{
Example *x = malloc(sizeof(Example));
/* initialize x */
return x;
}
and in addTopBotExample
void addTopBotExample(Example *example, int someVariable) {
Example *top = createTopExample(int someVariable); //(createTopExample returns a
//type Example based on some input)
Example *bot = createBotExample(int someVariable);
example->topExample = top;
example->botExample = bot;
return;
}

Ooooo, this is bad. The expression "Example top" in the addTopBotExample() function allocated that object on the stack. It'll be trashed after exiting from the function. (Same for "Example bot" on the following line.) Something like this will work better:
void addTopBotExample(Example **example, int someVariable) {
Example *top = createTopExample(someVariable); // NOTE THE *
Example *bot = createBotExample(someVariable); // NOTE THE *
(*example)->topExample = top; // NOT &top !!
(*example)->botExample = bot; // NOT &bot !!
return;
}
And you'll want to write createTopExample and createBotExample so they return pointers:
#include <stdlib.h> // For malloc!
Example *createTopExample(stuff) // Note *. It's returning a pointer.
{
Example *example = malloc(sizeof(Example)); // Allocate on the HEAP. Lives after this function call.
// Fill in the fields of example.
example->field1 = 25; // Note the "->": you're dereferencing a pointer.
example->title = "Example title";
return example;
}

Related

Using Memory Allocation with glib's g_new()

I have been using g_new() to allocate memory for a single struct which is ok in the following manner.
/*Structure*/
typedef struct
{
guint16 index;
gchar * date;
gchar * number;
}h_item;
/*allocation*/
h_item * my_h_item = g_new(h_item, 1);
/*freeing function*/
void free_h_item(h_item * item)
{
g_free(item->date);
g_free(item->number);
g_free(item);
}
I am now trying to do the same for an array[2] of the structs, for example
statically allocation is like this, but that would mean it's on the program stack.
h_item my_h_item[5];
I would like to dynamically allocate the same above, but I seem to have trouble when running the program...
/*Structure*/
typedef struct
{
guint16 index;
gchar * date;
gchar * number;
}h_item;
/*freeing function*/
void free_h_item(h_item * item)
{
g_free(item->date);
g_free(item->number);
g_free(item);
}
static h_item * my_h_item[2];
int main()
{
/*allocation*/
my_h_item[2] = g_new(h_item, 2);
my_h_item[0]->date = g_strdup("12345"); /*Test*/
return 0;
}
This program compiles but segfaults...
#0 0x00000000004007a7 in main () at struct_memory.c:30
30 my_h_item[0]->date = g_strdup("12345"); /*Test*/
Where is my allocation going wrong?
You have allocated my_h_item[2] and you are accesing my_h_item[0] which is not allocated
You need to allocate my_h_item[0] as well prior to using its elements
my_h_item[2] is not valid as my_h_item has only 2 elements, only my_h_item[0] and my_h_item[1] is valid
You said you wanted to create an array of 2 structs.
What you have created is an array of two pointers.
What you need to do is
static h_item * my_h_item;
and then
h_item = g_new(h_item, 2);
You can then use the two structs as h_item[0] and h_item[1] and the date inside it as
h_item[0].data = g_strdup(...);
Also g_* class of functions are non standard. Please use malloc and free.

Data saved in Stack content keep changing, can't increment

So here is my issue, I have been trying to figure this out for the last 5 hours, I have a header file, a tester file, and a c source file. I would really like to understand what is happening and why so I can avoid the issue in the future. The header file declares the struct but does not define it:
typedef struct Stack *StackP;
and in my source file, Stack.c I have defined the stack:
struct Stack
{
int top;
int capacity;
int count;
ItemT items;
};
where ItemT is defined as char *
in the tester file, the call goes:
StackP stackPtr = newStack();
and what I have for my newStack function located in the c source file is:
StackP newStack(void) {
struct Stack stack1;
StackP stackPtr = &stack1;
(stackPtr->items) = (ItemT)malloc(DEFAULT_CAPACITY*sizeof(ItemT));
(stackPtr->top) = -1;
(stackPtr->capacity) = DEFAULT_CAPACITY;
(stackPtr->count) = 0;
fprintf(stderr, "\nSuccesfully allocated memory to items...\n");
return stackPtr;
}
now, my push function is:
void pushStack(StackP stackPtr, ItemT item) {
if ((stackPtr->count) == (stackPtr->capacity)) {
fprintf(stderr, "\nERROR: Full stack.\n");
}
else {
stackPtr->items = item;
fprintf(stderr, "\nSuccessfully pushed %s on to the stack...\n", stackPtr->items);
(stackPtr->items)++;
(stackPtr->top)++;
(stackPtr->count)++;
}
}
My question is this: Have I don't something wrong in any of these blocks of code.
If I call a function that says:
return (stackPtr->count);
it will return a random set of numbers instead of 0, or 1. For instance, if I push 2 strings to the stack, instead of count being 2, count is 479622 or some other random long number. Why is this happening?
Again, I would like to know what I'm doing wrong and not just correct syntax because I really HAVE to understand this.
The program has undefined behaviour as it is returning the address of a local variable from a function:
StackP newStack(void) {
struct Stack stack1;
StackP stackPtr = &stack1;
return stackPtr;
}
stack1 no longer exists when newStack exits. stackPtr must point to dynamically allocated memory if it is to exist beyond the scope of the function:
StackP newStack(void) {
struct Stack stack1;
StackP stackPtr = malloc(sizeof(*stackPtr));
if (stackPtr)
{
}
return stackPtr;
}
See Do I cast the result of malloc?

Contents of array changing within a struct in C

I'm currently stumped on this problem I have.
I have this structure:
typedef struct corgi_entry {
unsigned pup; //Supposed to be hex
} corgi_entry, *Pcorgi_entry;
typedef struct corgi {
Pcorgi_entry *arrayCorgiHead;
} corgi, *Pcorgi;
I have this variables:
static corgi c1;
In an init function, I malloc my arrayCorgiHead
c1.arrayCorgiHead = (Pcorgi_entry *)malloc(sizeof(Pcorgi_entry) * corgiNumber));
The corgiNumber is just a placeholder, it can be however many, just the size of the index.
Given this, later on I'm running a loop. Every iteration of the loop, I'm given a corgi and an index from somewhere. If at that index it is null, I'm supposed to make a corgi and assign the pup data to be the same. If it's not null, I check the corgi I'm given with the corgi at the index to see if the pup match.
if(c1.arrayCorgiHead[index] == NULL){
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
printf("Corgi Made!, pup: %10x\n", c1.arrayCorgiHead[index]->pup); //For debug purposes
}
else{ //Not null
if(c1.arrayCorgiHead[index]->pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", c1.arrayCorgiHead[index]->pup); //For debug purposes
//Do stuff
}
}
Here's the problem. In the file where I give this code the "external" index/corgis, on my third entry I give it the same as the first:
Index: 1 Corgi{pup = 123}
Index: 2 Corgi{pup = 456}
Index: 1 Corgi{pup = 123}
For some reason, when it processes the third entry, it says that it doesn't match. I print out the corgi pup at the array index, and I get some really weird number that doesn't make any sense (9814008 or something). This random number changes every time I ./corgisim and whatnot.
I do not touch the array at any other point besides what's written here. Why would my data be changing after a loop iteration?
*edit: To clarify my last point, my printf statements goes
Corgi Made!, pup: 123
Corgi Made!, pup: 456
Corgi Found?, pup: 20138940139 (random number that changes every time I run my program)
This code has been abbreviated for the sake of clarity (and corgi-ed, I don't know if that makes things clearer or not. The numbness in my brain has driven me insane). As you may be able to tell from the code, I'm not very familiar with C.
Thanks!
Edit 2: Thanks guys, solution worked like a charm! Pretty long question for a pretty simple problem, but I'm glad I figured it out. Much appreciated.
Here is the problem:
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
Variable newcorgi_entry is a local variable, which is allocated on the stack. Therefore, once outside the variable's scope of declaration, you cannot rely on &newcorgi_entry as a valid memory address.
Here is the solution:
You should allocate the corgi_entry instance on the heap instead:
corgi_entry* newcorgi_entry = malloc(sizeof(corgi_entry));
newcorgi_entry->pup = pupnumber;
c1.arrayCorgiHead[index] = newcorgi_entry;
The problem is how you "allocate" memory:
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
Here, newcorgi_entry is allocated on the stack. Then you assign the address of that stack variable to your array. Problem is, as soon as your function runs out of scope that memory is free to be used by any other function and sooner or later gets overwritten by some other code.
There are two solutions: either allocate on the heap using malloc, or don't use pointers at all. The first solution looks like this:
Pcorgi_entry newcorgi_entry = malloc(sizeof(corgi_entry));
newcorgi_entry->pub = pubnumber;
c1.arrayCorgiHead[index] = newcorgi_entry;
For the second solution there are a few variations. Here's one:
typedef struct corgi_entry {
unsigned pup;
int inUse;
} corgi_entry, *Pcorgi_entry;
typedef struct corgi {
corgi_entry *arrayCorgiHead; // "Head" is the wrong name here, IMHO.
} corgi, *Pcorgi;
static corgi c1;
// calloc clears the memory to 0
c1.arrayCorgiHead = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
if(!c1.arrayCorgiHead[index].inUse){
c1.arrayCorgiHead[index].pub = pubNumber
c1.arrayCorgiHead[index].inUse = 1;
printf("Corgi Made!, pup: %10x\n", c1.arrayCorgiHead[index].pup); //For debug purposes
}
else{
if(c1.arrayCorgiHead[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", c1.arrayCorgiHead[index].pup); //For debug purposes
//Do stuff
}
}
I think the corgi struct and its variable are unnecessary. I'd do it like this instead:
typedef struct corgi_entry {
unsigned pup;
int inUse;
} corgi_entry;
static corgi_entry *corgis;
// calloc clears the memory to 0
corgis = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
if(!corgis[index].inUse){
corgis[index].pub = pubNumber
corgis[index].inUse = 1;
printf("Corgi Made!, pup: %10x\n", corgis[index].pup); //For debug purposes
}
else{
if(corgis[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", corgis[index].pup); //For debug purposes
//Do stuff
}
}
Yet another way would be if you define the "pubNumber" 0 to be illegal so you can us it as a sentinel instead:
typedef struct corgi_entry {
unsigned pup;
} corgi_entry;
static corgi_entry *corgis;
// calloc clears the memory to 0
corgis = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
// pub number 0 is illegal, so it must be an unused entry
if(corgis[index].pub == 0) {
corgis[index].pub = pubNumber
printf("Corgi Made!, pup: %10x\n", corgis[index].pup); //For debug purposes
}
else{
if(corgis[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", corgis[index].pup); //For debug purposes
//Do stuff
}
}

Malloc Typedef Struct Problems

I am working on building a threads library and for some reason have run into a simple malloc problem that I can't fix right now. I'm sure it's something simple I'm just missing it.
In my main.c I have the following code:
//declare testSem
tasem_t testSem;
int main(int argc, char **argv){
ta_libinit();
//initialize testSem
ta_sem_init(&testSem, 5);
//wait test
ta_sem_wait(&testSem);
the relevant code in my thread library is as follows:
void ta_sem_init(tasem_t *sema, int value)
{
//malloc the semaphore struct
sema = malloc(sizeof(tasem_t));
//error check
if(sema == NULL)
{
printf("could not malloc semaphore");
exit(0);
}
//initialize with the given value
sema->val = value;
printf("SemaVal = %i\n", sema->val);
}
void ta_sem_wait(tasem_t *sema)
{
printf("SemaVal = %i\n", sema->val);
if(sema->val <= 0)
{
//not done yet
printf("SWAPPING\n");
}
else
{
printf("SemaVal = %i\n", sema->val);
sema->val = sema->val + 1;
}
}
Here is the struct from my header file:
//struct to store each semas info
typedef struct tasem_t_struct
{
//value
int val;
//Q* Queue
//int numThreads
}tasem_t;
The output I get from this is:
SemaVal = 5
SemaVal = 0
SWAPPING
So evidently, I'm not mallocing my struct correctly as the value inside is lost once I go out of scope. I know I must just be forgetting something simple. Any ideas?
You can't seem to decide who's responsible for allocating your tasem_t structure. You have a global variable for it and pass its address to ta_sem_init. But then you have ta_sem_init dynamically allocate a brand new tasem_t structure, saving its address to sema, a local function argument, so that address gets lost when it falls out of scope.
Pick one, either:
Make ta_sem_init initialize an existing tasem_t variable.
Make ta_sem_init allocate and initialize a new tasem_t structure and then return its address (either directly or via a tasem_t** output parameter).

using malloc for the life of the program

gcc 4.4.4 c89
I have always thought of using malloc for the life of the project for being the scope.
But I am just wondering if my idea is the best practice. For example, I initalize an instance of the struct in main. And create 2 functions for creating and destroying. I am just wondering if this is the right thing to do.
I have some skeleton code below.
Many thanks for any advice,
typedef struct Network_dev_t {
size_t id;
char *name;
} Network_dev;
Network_dev* create_network_device(Network_dev *network)
{
network = malloc(sizeof *network);
if(network == NULL) {
return NULL;
}
return network;
}
void do_something(Network_dev *network)
{
/* Do something with the network device */
}
void destroy_network_device(Network_dev *network)
{
free(network);
}
int main(void)
{
Network_dev *network = NULL;
network = create_network_device(network);
/* Do something with the network device */
do_something(network);
destroy_network_device(network);
return 0;
}
Looks good.
I have a point or 2 about create_network_device
Network_dev* create_network_device(Network_dev *network)
no need to pass in a pointer; I'd rather have Network_dev* create_network_device(void)
{
network = malloc(sizeof *network);
the if is not really necessary; if malloc failed the return network at the end of the function is the same as return NULL.
if(network == NULL) {
return NULL;
}
If the allocation succeeded you might want to insure the struct members are in a know state here
/* if (network) { */
/* id = 0; */
/* name = NULL; */
/* } */
return network;
}
This code looks fine to me. I agree with pmg that your create_network_device could use a little work. Just to pull together what he said and make things clearer, here is exactly how I would write the function:
Network_dev *create_network_device()
{
Network_dev *network = malloc(sizeof(*network));
if (network) {
network->id = 0;
network->name = NULL;
}
return network;
}
It is best to allocate memory and free memory in the same function. Just like you open and close files in the same function. You did this by creating and destroying a Network_dev in the main() function, which is good. This makes it easy to confirm that all malloced locations are also freed.
It is best to malloc() something as late as possible and free() it as soon as possible. That is, hold the memory for as short as possible. If your program's job is to do something with Network_dev, you did all right. If your program does a lot of other things, you should do them before malloc() or after free().

Resources