Allocate struct on the heap in C [duplicate] - c

This question already has answers here:
How to malloc inside a function and return pointer in C?
(3 answers)
C: adding element to dynamically allocated array
(3 answers)
Closed 8 years ago.
#include <stdio.h>
#include <stdlib.h>
struct myStruct
{
int number;
};
void
allocateMem(struct myStruct *struct1)
{
struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
}
int
main(int argc, char *argv[])
{
struct myStruct *struct1 = NULL;
allocateMem(struct1);
printf("number: %d\n", struct1->number);
return 0;
}
Hello citizens of StackOverflow, I seek your assistance.
What I am trying to do is allocate a struct using heap space rather than stack space; and I am trying to do the allocation inside of a function. No matter how much I mess with this I always get either a segmentation fault or several compiler warnings.
I'm doing something here incorrectly, but I can't figure out what, I've been all over StackOverflow and the general internet trying to find an example or post that relates to my issue but I have not found anything.
If you could tell me what I'm doing wrong, or just point me in the right direction I would be extremely grateful.
Thank you everyone for your quick and accurate replies. You were correct, I needed a pointer to a pointer, my code works now thanks to your help.

In this function,
void
allocateMem(struct myStruct *struct1)
{
struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
}
struct1 is passed by value. Any changes you make to it in the function are not visible from the calling function.
A better alternative:
struct myStruct* allocateMem()
{
struct myStruct *struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
return struct1;
}
Change the calling function to:
int
main(int argc, char *argv[])
{
struct myStruct *struct1 = allocateMem();
printf("number: %d\n", struct1->number);
// Make sure to free the memory.
free(struct1);
return 0;
}

A pointer is just an integer in reality, when you pass in struct1 to your function since struct1 is null you are just passing in a 0 to your function in reality. that value gets passed on the stack and you do a heap allocation and update the stack value with the new address. but when you return from the function, that value just gets popped of the stack and you have leaked that memory. the value of struct1 in main (which is also on the stack still keeps its value 0(NULL). so you have to pass in a pointer to your pointer if you want to update that value, or what might be easier is just to return the malloc'd pointer from your function.
This is one way you could modify your function to work:
#include <stdio.h>
#include <stdlib.h>
struct myStruct
{
int number;
};
struct myStruct*
allocateMem()
{
struct myStruct* struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
return struct1;
}
int
main(int argc, char *argv[])
{
struct myStruct *struct1 = allocateMem();
printf("number: %d\n", struct1->number);
return 0;
}

Because you are changing the struct1 pointer in the method, you need to either return the pointer to the caller, or pass it as a double pointer (address of the caller's pointer), e.g.
Return:
struct myStruct* allocateMem()
{
struct myStruct* struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
return struct1;
}
Double pointer:
void allocateMem(struct myStruct **struct1)
{
With the allocation and usage as per #Grijesh's comments below.

Related

Adding item to a stack make it crash

I am trying to implement on my own (in order to understand it better) the Stack data structure in C language.
Here is what I've got so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stack{
//Data_Strucure: Stack of intgers
int *stack;
int size_of_stack;
int elem_in_stack;
};
struct stack *creat_stack(unsigned int);
int push(struct stack *, int);
int pop(struct stack *);
int empty(struct stack *);
int peek(struct stack *);
int main(int argc, char *argv[]){
int new_elem = 13;
struct stack *new_stack = creat_stack(5);
printf("%d %d\n", new_stack->size_of_stack, new_stack->elem_in_stack);
//Crashes from here
push(new_stack, new_elem);
printf("%d\n", new_stack->stack[new_stack->size_of_stack]);
}
struct stack *creat_stack(unsigned int size){
struct stack tmp;
struct stack *ret_stack = &tmp;
if((ret_stack->stack = malloc(sizeof(int) * size)) == NULL){
fprintf(stderr, "Unable to allocate memory for the Stack.\n");
exit(1);
}
ret_stack->size_of_stack = size;
ret_stack->elem_in_stack = 0;
return ret_stack;
}
int push(struct stack *stack, int nw_elem){
int pos = stack->size_of_stack - stack->elem_in_stack;
if(stack->size_of_stack == 0)
return 1;
stack->stack[pos] = nw_elem;
}
The compiler returns me no error. Though I don't understand why it crashes after push() is called.
Please, if possible, instead of solution code, can you just tell me where the error is? This way I can understand how it effect the whole program and try to solve it on my own (so next time won't happen again).
Thanks is advance for any of your usefull answers.
At least the function creat_stack is incorrect.
struct stack *creat_stack(unsigned int size){
struct stack tmp;
struct stack *ret_stack = &tmp;
//...
return ret_stack;
}
It returns a pointer to the local object tmp that will not be alive after exiting the function. So the returned pointer will be invalid and dereferencing such a pointer invokes undefined behavior.
Instead you could return the object itself from the function. That is the function declaration could look like
struct stack creat_stack(unsigned int size);
And in main you can write
struct stack new_stack = creat_stack(5);
Also the function push does not change the data member elem_in_stack And again it invokes undefined behavior because when elem_in_stack is equal to 0 then the function tries to write to memory outside the dynamically allocated array. That is in this case pos is equal to size_of_stack.
int push(struct stack *stack, int nw_elem){
int pos = stack->size_of_stack - stack->elem_in_stack;
if(stack->size_of_stack == 0)
return 1;
stack->stack[pos] = nw_elem;
}

Embedded memory allocation and scope

If I want to create a structure initialization functions that return a pointer to the initialized structure members, will the allocated memory to the data array in new_foo still be valid outside the function?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct structure{
char* data;
size_t num;
}foo_t;
foo_t* new_foo(size_t num);
int main(void){
foo_t* foo = new_foo(32);
while(1){;}
}
foo_t* new_foo(size_t num){
foo_t* self;
char temp[num];
self->data = temp;
self->num = num;
return self;
}
I wanted to take a look at the assembly code to see if anything jumped out at me, the only thing that potentially makes me thing memory is still valid is that there are no stack operations associated with
char temp[num];
self->data = temp;
but it's been a while since I had to look at assembly code.
https://godbolt.org/z/5Wx4TY
[EDIT] Modified new_foo
foo_t* new_foo(size_t num){
static foo_t self = {NULL, 0};
char data_array[num];
self.data = temp;
self.num = num;
return &self;
}
The function has undefined behavior.
foo_t* new_foo(size_t num){
foo_t* self;
char temp[num];
self->data = temp;
self->num = num;
return self;
}
For starters the pointer self is not initialized and has indeterminate value.
The variable length array temp is a local variable of the function that will not be alive after exiting the function. So any pointer to it returned from the function will be invalid.

Why am i getting ' request for member ‘******’ in something not a structure or union'?

I'm getting the error for p->letter = 'A' and p->age = '9'. I don't know what is going wrong.
#include<stdio.h>
#include<stdlib.h>
struct player {
char letter;
int age;
};
typedef struct player *player_t;
int main (void)
{
player_t* p;
p = (player_t*)malloc(1 * sizeof(player_t));
if (p == NULL)
{
/* EDITED by #ahmedmasud removed original printf line for language */
printf("Unable to allocate\n");
return 1;
}
p->letter = 'A';
p->age = '9';
free(p);
return 0;
}
As many folks have pointed out you have a problem because in using typedef you went one step too far :-). Using typedef to recast types is meant for increasing clarity whereas the way you're using it decreases clarity.
Let me first show your example with the correct approach:
#include <stdio.h>
#include <stdlib.h>
struct player {
char letter;
int age;
};
/* typedef struct player *player_t; NOT NEEDED */
int main (void)
{
struct player *p;
p = malloc(sizeof(*p)); /* used *p for sizeof instead of struct player */
if (p == NULL)
{
fprintf(stderr, "Unable to allocate memory\n");
return 1;
}
p->letter = 'A';
p->age = '9';
free(p);
return 0;
}
When to use typedef foo_t bar_t
When it makes things clearer, e.g. stdint.h does this for integers. Say, you want a 32-bit unsigned int, you would use uint32_t which is appropriately typedef'd for various architectures to give you what you expect.
When NOT to use typedef struct foo foo_t
Pretty much all the time.
When it's OK to use typedef struct foo foo_t
Now for the reasons behind the changes, typedef struct foo foo_t is discouraged except when struct foo is opaque, typically when you are writing a C API where the structure is accessed through predefined access functions that have a longer life than internal structure.
Why use sizeof(*p) instead of sizeof(struct player) ?
In case, for some reason, you decide to change what *p is then all you have to do is change the declaration, and not worry that it's not going to get appropriately allocated.
This is an example of why you shouldn’t typedef a pointer.
player_t is a typedef for struct player *. You then define p as a player *, which means the full type of p is struct player **. The fact that you had a pointer hidden in a typedef ended up confusing you, and it can similarly confuse others who read your code.
Remove the pointer from the typedef and it will work as expected:
typedef struct player player_t;
You typedef
typedef struct player *player_t;
... so player_t is a type of pointer to struct player.
Then you define a variable:
player_t* p;
p is a pointer to pointer to struct player. Remove the *.
player_t* p; is not a pointer to struct player; it is a pointer to a pointer to struct player. Remove the * from the variable declaration and from the type cast before the call to malloc (you do not need that cast, anyway).
Change these two lines:
player_t* p;
p = (player_t*) malloc(1*sizeof(player_t));
into:
player_t p;
p = (player_t) malloc(1*sizeof(struct player));
p is of type player_t, which is already defined as a pointer to a player. No need for another * in its definition. Also, you need to allocate the size of the original struc, not the size of the pointer (sizeof(player_t) is the size in bytes of a pointer, not the size of the struct player).
Apart from what others pointed, Firstly typedef a pointer variable is not considered as good practice as hiding the * makes the code hard to read. Read Is it a good idea to typedef pointers?
Though if you want to typedef a pointer then do like below
typedef struct player {
char letter;
int age;
}player_t, *player_p; /* player_t is normal struct & player_p is pointer struct, here when someone see _p at the end of variable means it has * */
Next you need to allocate memory for player_p for e.g
player_p ptr = malloc(sizeof(struct player)); /* here don't take like "player_p *ptr" as player_p is already a pointer to struct */
if(ptr == NULL) {
/* error handling #TODO */
}
Later you can access structure member like
ptr->letter = 'A';
ptr->age = '9'; /* age is integer member, you may want to assign integer value directly like 57 instead of '9' */
And free the dynamically created memory by calling free().
free(ptr);
Sample code
typedef struct player {
char letter;
int age;
}player_t, *player_p;
int main(void) {
player_p ptr = malloc(sizeof(struct player));
if(ptr == NULL) {
/* error handling #TODO */
}
ptr->letter = 'A';
ptr->age = 50;
printf("%c .. %d \n",ptr->letter,ptr->age);
free(ptr);
return 0;
}

malloc of array in struct passed as argument

I would like to allocate memory for arrays that are members of a struct I need to use, inside a function that takes the struct as an argument.
arg->A.size=(int*) malloc(N*sizeof(int));
will not compile (request for member 'size' is something not a structure.
arg->A->size=(int*) malloc(N*sizeof(int));
will throw a segmentation fault error
Any help will be appreciated.
Here is the code, thanks:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// struct A
struct A {
int dim; // dimensions
int* size; // points per dim array
double* val; // values stored in array
int total; // pow(size,dim)
};
// struct B that uses A
struct B {
int tag;
struct A* A;
};
int function_AB(struct B* B);
int main(void){
struct B B;
function_AB(&B);
return 0;
}
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A->size=(int*) malloc(N*sizeof(int));
return 0;
}
You simply haven't allocated memory for struct A *A. Before assigning anything to A->size you would first need to do something like
B->A = malloc(sizeof(struct A));
The second case is correct, but crashes because the A inside the B declared in main has not been assigned a value. You probably want something like
struct A A;
struct B B;
B.A = &A;
function_AB(&B);
When you have structure pointer in another structure, first you need to allocate memory for that. then allocate the memory for structure members!
struct B {
int tag;
struct A* A;
};
Here A is a pointer to a structure called A. First allocate memory for this, then allocate memory for the elements of struct A
arg->A = malloc(sizeof(struct A));
then do-
arg->A->size = malloc(N*sizeof(int));
Try the following changes in your int function_AB(struct B* arg)-
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A = malloc(sizeof(struct A)); // First allocate the memory for struct A* A;
arg->A->size = malloc(N*sizeof(int)); // Allocate the memory for struct A members
arg->A->val = malloc(N*sizeof(double));
// do your stuff
// free the allocated memories here
free(arg->A->size);
free(arg->A->val);
free(arg->A);
return 0;
}
And don't cast the result of malloc()!

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