Dynamic allocation of structs in C - c

I have a problem with dynamic memory allocation. Here is the code so please help.
#include <stdio.h>
int i;
typedef struct{
int A;
}node;
typedef struct Model
{
node *m;
} Model;
Model M;
void initialize(Model *a, int size)
{
a->m = (node*) malloc(size);
}
void model_init(Model *a, int len)
{
int i;
for (i=0;i<len;i++) a->m[i].A = 20;
}
int main()
{
initialize(&M ,10);
model_init(&M, 10);
for (i=0;i<10;i++) printf("%d\n",M.m[i].A);
}
I am trying to make a Model that has 10 nodes and I want to assign values to nodes in variable A. The printf shows (-1819044973, -1819044973, 14128019, 3969, 0, 0, 0 ...)
I just want it to say for example M.m[2].A=20
What am I doing wrong? please help.
TY

void initialize(Model *a, int size)
{
a->m = (node*) malloc(sizeof(node) *size); // NOTICE HERE!!!!
}

Your initialize function allocates a number of bytes then model_init later assumes that many node instances will be available. node is larger than 1 byte (at least sizeof(int) bytes) so you write beyond the end of allocated memory.
The easiest fix is to change initialize:
void initialize(Model *a, int elements)
{
a->m = malloc(elements * sizeof(node));
}

For more information on the fact that you don't have to cast malloc :
Do I cast the result of malloc?

Related

void double pointer to other types

typedef struct
{
void **heapArr;
int last;
int capacity;
int (*compare) (void *arg1, void *arg2);
} HEAP;
int heap_Insert( HEAP *heap, void *dataPtr);
I was doing my assignment of insert data to heap with abstract data type.
I allocated memory to heap, but I got problem of inserting data to heap.
I can't find out how to make void double pointer to char or int arrays.
void *x=dataPtr;
heap->(*heapArr)=&x;
I tried this way but I got failed. How can I make void double pointer to other type?
Why heapArr is a double pointer ? I think a single pointer is enought...
typedef struct
{
void *heapArr;
int last;
int capacity;
int (*compare) (void *arg1, void *arg2);
} HEAP;
int heap_Insert( HEAP *heap, void *dataPtr){
heap->heapArr = dataPtr;
return 0;
}
int main(void){
char str[] = "hello";
HEAP heapString;
heap_Insert(&heapString, str);
char * str_get = heapString.heapArr;
printf("%s\r\n", str_get );
int val = 101;
HEAP heapInt;
heap_Insert(&heapInt, &val);
int * int_get = heapInt.heapArr;
printf("%i\r\n", *int_get);
}
If you want to convert void* to char*, then following is the method -
(say void *data)
char *a = (char*) data;
Similarly for double pointer,
char **a = (char**) heapArr;
Simply typecast will do the conversion. Please try and comment back what you see.

C - Program crash after free()

I have a program that creates a struct named Stack that holds a pointer to an array of ints and an int that shows the size of this array.
I have functions to:
Initialize the struct with empty values
Push integers to the array (dynamically allocate more memory and write a value to it)
Pop an int from the array
However, when I try to pop the last element by freeing the memory it occupies, my program crashes.
What am I doing wrong here?
Is my process correct?
I realize the problem is probably that I'm trying to free a segment of memory that has not been allocated dynamically, but I just don't see where the issue is exactly.
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
struct Stack{
int *array;
int size;
};
typedef struct Stack Stack;
void initStack(Stack *stack);
void push(Stack *stack, int value);
int pop(Stack *stack);
int main()
{
Stack firstStack;
initStack(&firstStack);
push(&firstStack, 1222);
pop(&firstStack);
push(&firstStack, 555);
for(int i = 0; i < firstStack.size; ++i){
printf("#%d: %d (%p) ", i , firstStack.array[i], &firstStack.array[i]);
}
return 0;
}
void initStack(Stack *stack){
stack->array = NULL;
stack->size = 0;
}
void push(Stack *stack, int value){
int size = stack->size;
int newSize = size + 1;
stack->array = realloc(stack->array, newSize * sizeof(int));
if(stack->array != NULL){
stack->array[size] = value;
stack->size = stack->size + 1;
}
else{
printf("MALLOC ERROR");
}
}
int pop(Stack *stack){
int lastValue = stack->array[stack->size];
int lastIndex = (stack->size)-1;
int* lastAddress = (stack->array)+lastIndex;
free(lastAddress);
stack->size = (stack->size) - 1 ;
printf("memory free\n");
return lastValue;
}
int* lastAddress = (stack->array)+lastIndex;
free(lastAddress);
is wrong because lastAddress may not be an address allocated via malloc() family by adding lastIndex.
Remove the line
free(lastAddress);
If you want the system to change tha allocated size, you should change the line to
stack->array = realloc(stack->array, ((stack->size) - 1) * sizeof(int));
This is a problem:
int* lastAddress = (stack->array)+lastIndex;
free(lastAddress);
The argument to free must be an address value returned from malloc, calloc, or realloc - you cannot free memory at an arbitrary address, even within a dynamically allocated block.

Add values to a tree

I'm trying to add values to a binary search tree so for that I've written two functions one that create a new node and another which insert these values to the tree
So this is the code
typedef struct Node {
void *data;
struct Node *left;
struct Node *right;
} Node;
Node *createNode(void *data,size_t s){
Node *newNode = (Node *)malloc(s * sizeof(Node));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
void addValueBt(Node ** node, void *data, size_t s,int (* compar)(const void *, const void *)){
if (*node == NULL)
*node = createNode(data,s);
else if (compar((*node)->data,data) > 0)
addValueBt(&(*node)->left, data, s, compar);
else
addValueBt(&(*node)->right, data, s, compar);
}
When I call addValueBt in the main with two different ways (but normally seems to be the same thing) I don't get the same result
1st way:
int main(){
Node *root = NULL;
for(int i = 0; i < 10; i++)
addValueBt(&root, &i, 1, myCompar);
printBt(root,print);//print the whole tree
}
The display gives this:
10
10
10
10
10
10
10
10
10
10
2nd way:
int main(){
int a = 8, b = 9, c = 5, d = 1;
addValueBt(&root, &a, 1, myCompar);
addValueBt(&root, &b, 1, myCompar);
addValueBt(&root, &c, 1, myCompar);
addValueBt(&root, &d, 1, myCompar);
printBt(root,print);
}
The display:
1
5
8
9
"myCompar" compares between two integers
My question is: why it doesn't work when we use the function 'addValueBt' in the loop ?
(normally it should give the same result as for the other one )
Primary problem
As user3386109 correctly pointed out in a comment, the primary problem is that you're storing a pointer to the data in your tree, not a copy of the data. All the nodes end up pointing at the same location, so when that location changes, the value pointed at by the tree changes in all nodes at once.
Secondary issues
In a collection of comments (some of them responses to comment questions by Yasmine, the OP), I noted:
This is tangential to your main problem, but the parameter s is initially confusing. It's always 1 because you only allocate one node at a time. If it was larger, you'd waste the extra space that createNode() does allocate but does not initialize. You could stop using s (assume 1) without causing problems in the visible code.
I mean that in Node *createNode(void *data, size_t s) { Node *newNode = (Node *)malloc(s * sizeof(Node));, you allocate an array of Node structures of the size given by s. However, you initialize only the first structure allocated, and you don't record the size of the array anywhere. This doesn't matter because if you track the calls from main() to addValueBt() to createNode(), the value of s is always 1. But because it is always 1, you really have no need to pass it, so you can simplify the calls all the way down the calling chain.
Note that #user3386109: has identified the problem. You store the same pointer in each element of the tree, so when the pointed at value changes, all the elements of the tree change at the same time. And if the pointed at value goes out of scope, you get undefined behaviour. You either need to make a copy of the data in the createNode() function, which means that you need to know how big the data is so that you can allocate new space to store it, or you need to ensure that a different pointer is passed to the code each time, and those pointers remain valid until the tree is freed.
You can see with your working code, you pass a different pointer each time (a pointer to a different variable). When you repeatedly pass a pointer to the same variable, the same address is stored, so the current value stored at that address is used by all the nodes; they all have the same value.
Part of the problem comes from using void *data; instead of a simple int data;. For the immediate purposes, life would be much, much simpler if your data structure used int data;. You'd have:
Node *createNode(int key)
{
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->data = data; newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
If you store void *, you really need to know how long the data you're storing pointers to is, so that you can make copies, etc. Your comparator can make assumptions about the length (and you'll be OK as long as those assumptions are correct). So, you'd need:
Node *createNode(void *data, size_t len)
{
void *copy = malloc(len);
memmove(copy, data, len);
Node *newNode = (Node *)malloc(s * sizeof(Node));
newNode->data = copy;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
Yasmine commented:
I know but I have to do that so that it can be used with other types like float or char.
At that point, I started to produce the code below.
Working code
Here's an offering dealing with the points made in my comments.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct Node
{
void *data;
size_t datalen;
struct Node *left;
struct Node *right;
} Node;
static int cmp_dbl(const void *p1, const void *p2);
static int cmp_int(const void *p1, const void *p2);
static void freeBt(Node *node);
static void printBt(Node *node, void (*print)(const void *));
static void print_dbl(const void *p);
static void print_int(const void *p);
extern Node *createNode(void *data, size_t len);
extern void addValueBt(Node **node, void *data, size_t len, int (*compar)(const void *, const void *));
Node *createNode(void *data, size_t len)
{
void *copy = malloc(len);
// Error check allocation!
memmove(copy, data, len);
Node *newNode = (Node *)malloc(sizeof(*newNode));
// Error check allocation!
newNode->data = copy;
newNode->left = NULL;
newNode->right = NULL;
newNode->datalen = len;
return newNode;
}
void addValueBt(Node **node, void *data, size_t len, int (*compar)(const void *, const void *))
{
if (*node == NULL)
*node = createNode(data, len);
else if (compar((*node)->data, data) > 0)
addValueBt(&(*node)->left, data, len, compar);
else
addValueBt(&(*node)->right, data, len, compar);
}
int main(int argc, char **argv)
{
unsigned seed = time(0);
if (argc == 2)
seed = atoi(argv[1]);
srand(seed);
printf("Seed: %u\n", seed);
Node *root = NULL;
for (int i = 0; i < 10; i++)
addValueBt(&root, &i, sizeof(i), cmp_int);
printBt(root, print_int);
freeBt(root);
root = NULL;
for (int i = 0; i < 10; i++)
{
double d = (double)rand() / RAND_MAX * 1000.0 + (double)rand() / RAND_MAX;
addValueBt(&root, &d, sizeof(d), cmp_dbl);
}
printBt(root, print_dbl);
freeBt(root);
return 0;
}
static int cmp_int(const void *p1, const void *p2)
{
int v1 = *(int *)p1;
int v2 = *(int *)p2;
return (v1 > v2) - (v1 < v2);
}
static int cmp_dbl(const void *p1, const void *p2)
{
double v1 = *(double *)p1;
double v2 = *(double *)p2;
return (v1 > v2) - (v1 < v2);
}
static void print_int(const void *p)
{
printf("%d\n", *(int *)p);
}
static void print_dbl(const void *p)
{
printf("%8.3f\n", *(double *)p);
}
static void printBt(Node *node, void (*print)(const void *))
{
if (node != 0)
{
printBt(node->left, print);
print(node->data);
printBt(node->right, print);
}
}
static void freeBt(Node *node)
{
if (node != 0)
{
freeBt(node->left);
freeBt(node->right);
free(node);
}
}
Here's an example run:
Seed: 1511037421
0
1
2
3
4
5
6
7
8
9
87.907
118.694
140.163
170.833
343.940
412.792
422.254
530.731
557.656
936.981
What changed?
I dropped the parameter s to addValueBt() and createNode(), but added a parameter size_t len. That defines the length of the data. The length is stored in size_t datalen in the Node structure.
The code in createNode() makes a copy of the data it is passed and stores that copy in the tree. This ensures that each node is unaffected by changes to the values in the calling code.
What was added?
I added code for the int comparator (you called yours myCompar(); I called mine cmp_int() because I also wanted to work with double), and a double comparator cmp_dbl(). I added printing functions print_int() and printf_dbl() — renaming your print to print_int. I added memory release function freeBt(). I added code for printBt().
The code playing with the command line arguments allows you to specify a seed of your choosing. It's a bit sloppy; I should probably be using strtoul() instead of atoi(). But it allows you to specify a number on the command line to be used as the seed, which will give you repeatability when you need it. The seed is reported so you can reproduce results. This is helpful when playing with random numbers — sometimes you want randomness, and sometimes you want repeatability.
What I didn't do
I didn't fix the printing code so that the structure of the tree is visible. You just get a list of numbers.
The code doesn't really use the datalen member of the structure, but
it could be useful to check consistency, or for recording the length of strings.

Sorting dynamic array in a structure with C qsort ()

I have a problem to sort an array (dynamically allocated) in a structure. Firstly, the idea was to order the array i in the structure in an ascendant order. Then I was thinking to order the array i maintaining instead the array j with the same "relationship" obtained when it was constructed the initial structure. I try to work for the first idea, but without any result with qsort.So this is my code... Any ideas? I think there is a problem in the construction of the comparing function..
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
int M =10;
int N =30;
int K = 10;
struct element {
int *i;
int *j;
int k;
};
struct element *create_structure();
void print_element(struct element *);
int compare (const void *, const void * );
struct element * sort(struct element *);
main()
{
srand(time(NULL));
struct element *lista;
int count;
lista=create_structure();
print_element(lista);
printf("\n");
lista=sort(lista);
}
struct element *create_structure()
{
int aux1,aux2,count,load;
struct element *structure;
structure = (struct element *) malloc (M*sizeof(struct element *));
structure->k=K;
structure->i= (int *)malloc(structure->k*sizeof(int));
structure->j=(int *)malloc (structure->k*sizeof(int));
for (count = 0; count < K; count ++)
{
aux1=rand()%N;
(structure->i)[count]=aux1;
do
{
aux2=rand()%N;
}while(aux2==aux1);
(structure->j)[count]=aux2;
}
return (structure);
}
void print_element(struct element *lista)
{
int count;
for(count = 0; count < K; count ++)
{
printf("%d %d\n",lista->i[count],lista->j[count]);
}
}
int compare(const void *a, const void *b)
{
struct element *ia = (struct element *)a;
struct element *ib = (struct element *)b;
int *ptr1=(ia->i);
int *ptr2=(ib->i);
return (*ptr1-*ptr2);
}
struct element * sort(struct element *list)
{
qsort(list, sizeof(list->i)/ sizeof(int) , sizeof(list->i), compare);
//qsort(list->i, K, sizeof(list->i), compare);
print_element(list);
return (list);
}
Sorry for being late to the party ! :)
So let's start first by mentioning the wrong statements in your code
>> First
in function create_structure() you want to allocate memory for your structure pointer
struct element *structure; // here your structure pointer is
//pointing to memory space of type struct element
structure = (struct element *) malloc (M*sizeof(struct element *));
|------------------------|
|
V
Here you are allocating memory space of type struct element* which is
wrong ! instead it must be sizeof(struct element)
Concerning the while loop in the same function I found that it is totally useless
aux1=rand()%N;
(structure->i)[count]=aux1; // the value is in aux1 variable
do
{
aux2=rand()%N;
}while(aux2==aux1); // the loop try to get the same value of aux1
// or you have just stored it in aux1
(structure->j)[count]=aux2; // it is easy to delete the while loop and
// change aux2 by aux1
>> Second
Concerning the sort
qsort(list, sizeof(list->i)/ sizeof(int) , sizeof(list->i), compare);
|-----|
|
V
It is not an adress of the array so it is Wrong !
after knowing the major problems here is a version of code based on your own code which works perfectly
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
int M =10;
int N =30;
int K = 10;
struct element {
int *i;
int *j;
int k;
};
struct element *create_structure();
void print_element(struct element *);
int compare (const void *, const void * );
void sort(struct element *); // changed the return value of sort
// to void as the argument will be changed directly because it is a
// pointer
int main()
{
srand(time(NULL));
struct element *lista;
lista=create_structure();
printf("\n--------- i --- j ---------\n\n");
print_element(lista);
printf("\n---------------------------\n");
sort(lista);
print_element(lista);
return 0;
}
struct element *create_structure()
{
int aux1=0,count=0;
struct element *structure;
// Changed the allocation of structure pointer
structure = (struct element *) malloc (sizeof(struct element));
structure->k=K;
structure->i= (int *)malloc(K*sizeof(int));
structure->j=(int *)malloc (K*sizeof(int));
for (count = 0; count < K; count ++)
{
aux1=rand()%N;
// we kept only the first aux1 and copied it in the two arrays
(structure->i)[count]=aux1;
(structure->j)[count]=aux1;
}
return (structure);
}
void print_element(struct element *lista)
{
int count=0;
for(count = 0; count < K; count++)
{
printf("row=%2d : %2d %2d\n",count+1,(lista->i)[count],(lista->j)[count]);
}
}
int compare(const void *a, const void *b)
{
// compare the values of two case of array pointed by i of type int
return *(int*)a-*(int*)b;
}
void sort(struct element *list)
{
// we will sort the array pointed by i which contains K elements
// of type int and size sizeof(int) by using the compare function
qsort(list->i, K , sizeof(int), compare);
}
Hope it helps ! :)
Note: Using this code in codeblocks v13.12 generates under linux (gcc version 4.8.2) wrong output !! [ It might be a BUG in Code::Blocks]
but using it with command line with gcc gives correct output !!

Malloc Member Array of Struct

I have a struct and an dynamic array inside the struct. I want to malloc this array but i don't really now how. I want that array void because i want the members of this array to be structs. As you can see i tried something but it doesn't really work
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct saf
{
int head;
void **stack;
int size;
}exp1;
void init(int n)
{
struct saf exp1->stack = malloc(n);
}
int main()
{
printf("Give size: ");
scanf("%d",&exp1.size);
init(exp1.size);
return 0;
}
exp1 isn't a pointer. Use
exp1.stack = malloc(n);
I believe you are looking for void *, e.g.,
void init (int n)
{
exp1->stack = malloc(sizeof(void *) * n);
}
You will have to cast it when you use it.
struct saf exp1.stack = malloc(n);
The above statement creates array of n memory locations and returns the void * pointer to the starting address. In this case stack should be single pointer i,e void *stack;
If you want stack to be a double pointer i,e void **stack then you should use
exp1.stack=malloc(sizeof(void *)*n);

Resources