Difference between pointers when malloc - c

I usually make myself a struct and I allocate memory for the struct and sometimes for buffers inside the struct. Like so:
typedef struct A
{
char *buffer;
int size;
} A;
Then when I malloc for the struct I do this. (I learned not to cast the malloc return here on SO.)
X
A *a = malloc(sizeof(a));
a->buffer = malloc(10*sizeof(a->buffer));
What is the difference between X and Y this?
Y
A *a = malloc(sizeof(*a));
a->buffer = malloc(10*sizeof(a->buffer));
They seem to be doing the same thing.

Neither is correct, the second one doesn't even compile.
You want either of these:
A * a = malloc(sizeof(A)); // repeat the type
// or:
A * a = malloc(sizeof *a); // be smart
Then:
a->size = 213;
a->buffer = malloc(a->size);

you should typecast it (A *) because calloc or malloc return void *.
A *a=(a*)malloc(sizeof(A));
suppose you want to allocate memory for buffer for 10 characters
a->buffer=(char *)malloc(sizeof(char)*10);

Related

How do I dynamically allocate memory to a pointer array inside a structure

here is what i have in done so far
struct test_case {
int n;
int *test[];
};
struct test_case *test_case_struct = (struct test_case *)malloc(
sizeof(struct test_struct) + 100 * sizeof(int));
I need to allocate n pointers in the "test" pointer array. As far as i know i need to allocate space to the structure and then some more for the pointer array, but when i try to compile this, i get the error
invalid use of sizeof operator for to incomplete type struct test_struct
if someone could please inform me how i can take the value of n as a user input and have int *test [n] made possible.
Don't repeat type names. You already stumbled over your own code twice because you did that. You made the mistake of typing the wrong struct tag and confusing int* for int.
A more hardy allocation would look like this
struct test_case *test_case_struct =
malloc(sizeof (*test_case_struct) + sizeof (test_case_struct->test[0]) * 100);
This here will allocate the size of whatever test_case_struct points at, plus 100 more of whatever test_case_struct->test[0] should be. Now you can play with the structure definition without breaking this call to malloc. And if you do perform a breaking change (like renaming test), you'll be notified by your compiler promptly.
You need to change
sizeof(struct test_struct)
to
sizeof(struct test_case)
as test_struct is not the correct structure type.
In a better way, you can also use the already-declared variable name, like
struct test_case *test_case_struct = malloc(
sizeof (*test_case_struct) + n * sizeof(int*));
That said, you need to allocate memory worth of int *s, not ints, for the flexible member.
Also, below is a snippet which shows the count is taken as user input
int main(void)
{
int n = 0;
puts("Enter the count of pointers");
if (scanf("%d", &n) != 1) {
puts("Got a problem in the input");
exit (-1);
}
struct test_case *test_case_struct = malloc( sizeof(struct test_case) + n * sizeof(int*));
printf("Hello, world!\n");
return 0;
}
Currently you are using flexible array(aka zero length array).
Which can be allocated as below.
struct test_case *test_case_struct =
malloc(sizeof (*test_case_struct) + 100 * sizeof (int *));
Note missing * for int and typo sizeof(struct test_struct) in your code.
Alternatively you can use pointer to pointer as below.
struct test_case {
int n;
int **test;
};
struct test_case *test_case_struct = malloc(
sizeof(*test_case_struct));
test_case_struct->test = malloc(100 * sizeof(int *)); // Allocates 100 pointers

What should I use as the argument of sizeof when malloc [duplicate]

This question already has answers here:
malloc(sizeof(int)) vs malloc(sizeof(int *)) vs (int *)malloc(sizeof(int))
(2 answers)
Closed 5 years ago.
I always confuse about what to put inside of sizeof when malloc
for example,
struct sth *p = malloc(sizeof(struct sth));
or
struct sth *p = malloc(sizeof(struct sth *));
or, char ***p = malloc(sizeof(WHAT_SHOULD_I_PUT_HERE));???
someday, some c guru told me that use the variable like this:
struct sth *p = malloc(sizeof(*p));
So i wrote some code:
void main() {
int n = 1000000, i;
char **p = malloc(sizeof(char *) * n); // works
//char **p = malloc(sizeof(**p) * n); // not work, segfault
for(i=0; i<n; i++) {
// p[i] = malloc(sizeof(char)); // works
// p[i] = malloc(sizeof(p[i])); // works
// p[i] = malloc(sizeof(*p[i])); // works
}
for(i=0; i<n; i++) {
free(p[i]);
}
free(p);
}
still get confused, any easy way to remember?
sizeof(struct sth) is the size your struct takes in memory.
sizeof(struct sth*) is the size of a pointer to struct sth (usually 4 or 8 bytes); actually it's the size of any pointer on your platform.
So you need:
struct sth *p = malloc(sizeof(struct sth));
But it is better to write:
struct sth *p = malloc(sizeof(*p));
sizeof(*p); being the size of the object p points to and as p points to struct sth, sizeof(*p) is the same thing as sizeof(struct sth).
When you write sizeof, the C compiler computes the actual size of what you gave it. When you type sizeof (*int) for instance, you ask the compiler to compute the size of a ... pointer ! That is 4 or 8 bytes (32, 64 bits respectively) depending on your machine architecture.
However, if you type sizeof (struct foo) it will return the amount of bytes a struct of type foo would occupy in memory.
At some point you need to create enough memory for a struct and its values. So generally you want to pass sizeof (struct foo) to malloc.
If you want to use the *p rule then in the case below you need to do
char **p = malloc(sizeof(*p) * n);
Even if you have char ***p you would still use
char ***p = malloc(sizeof(*p) * n);

What is wrong with my dynamically allocated array of pointers to structs?

I have the following program that references array elements through a double pointer.
typedef struct {
int num1;
int num2;
int num3;
} DATA_SET;
typedef struct {
int structID;
DATA_SET *data_set_array; // Pointer to an array of DATA_SET structs
} MY_STRUCT;
int main () {
MY_STRUCT *Struct1;
DATA_SET **DataSetArray; // Array of pointers
Struct1 = malloc(sizeof(MY_STRUCT));
Struct1->data_set_array = malloc(sizeof(DATA_SET*)) //Allocate mem for the pointer to array of DATA_SETs
DataSetArray = malloc(sizeof(DATA_SET*) * 2) // Allocate mem for an array of 2 DATA_SET pointers
DataSetArray[0] = malloc(sizeof(DATA_SET)) // Allocate mem for the actual DATA_SET struct
DataSetArray[0]->num1 = 1;
DataSetArray[0]->num2 = 2;
DataSetArray[0]->num3 = 3;
DataSetArray[1] = malloc(sizeof(DATA_SET)) // Allocate mem for the actual DATA_SET struct
DataSetArray[1]->num1 = 1;
DataSetArray[1]->num2 = 2;
DataSetArray[1]->num3 = 3;
memcpy(Struct1->data_set_array, *DataSetArray, sizeof(DATA_SET*); //Copy data set array into Struct1
When I print all the data out in Struct1, i get:
Struct1->data_set_array[0].num1 = 1
Struct1->data_set_array[0].num2 = 2
Struct1->data_set_array[0].num3 = 3
Struct1->data_set_array[1].num1 = 50 //This should be 1
Struct1->data_set_array[1].num2 = 50 //This should be 2
Struct1->data_set_array[1].num3 = 65 //This should be 3
Seems to be misuse/data corruption for the 2nd element in the array.
I know there's probably different ways to do this, but I wanted to get familiar with referencing the array indices via double pointers. Am I allocating memory properly? I have a feeling the memcpy is incorrect.
Struct1->data_set_array = malloc(sizeof(DATA_SET*)
/* ^ wrong */
DataSetArray = malloc(sizeof(DATA_SET*) * 2)
/* ^ wrong */
You need to do sizeof(DATA_SET) because that is the actual size of a struct, not a pointer to a DATA_SET struct.
You're making the mistake of allocating only the size of a pointer times 2, which in many cases can be smaller than you'd hope for.
memcpy(Struct1->data_set_array, *DataSetArray, sizeof(DATA_SET*);
This is also wrong. You must copy the sizeof(DATA_SET). Keep in mind that sizeof(DATA_SET) is not equal to sizeof(DATA_SET*). A pointer's size in bytes is the same regardless of the type of pointer.
What is wrong with my dynamically allocated array of pointers to structs?
DataSetArray is an array of pointers to struct and there is not anything wrong with it.
The problem is 2 other things:
You can't use memcpy on an array of pointers to struct. The memory isn't consecutive.
Further, data_set_array is not an array of pointers to struct so you are trying to copy between incompatible types.
I guess you basically want to create a Double Dimension array. So basically you can do the code like this
struct abc {
int i;
};
struct abc **arr;
arr = (struct abc **) malloc(sizeof(struct abc) * 2);
arr[0] = (struct abc*)malloc(sizeof(struct abc));
arr[0]->i = 100;
arr[1] = (struct abc*)malloc(sizeof(struct abc));
arr[1]->i = 200;
One thing that you need to remember is that the outer array is just a pointer, so it doesn't need to be sizeof(abc) , it could very well be sizeof(int*) / sizeof (void*) etc.
so basically the above code could be written as
struct abc **arr;
arr = (struct abc **) malloc(sizeof(int *) * 2);
arr[0] = (struct abc*)malloc(sizeof(struct abc));
arr[0]->i = 100;
arr[1] = (struct abc*)malloc(sizeof(struct abc));
arr[1]->i = 200;
Hope this helps in underlying memory management you want to do with your code

In C, how do I allocate space for my struct?

I built a function that I'm trying to use to dynamically allocate memory for my struct like so. Just can't seem to get it to work
typedef struct My_Struct
{
char **array
}MyStruct
MyStruct * createMyStruct(int length)
{
MyStruct->array = malloc(sizeof(char *) * (length + 1));
}
int main(void)
{
MyStruct *new1 = createMyStruct(10);
return 0;
}
It's simple as allocating sizeof(MyStruct) and casting to MyStruct ptr:
MyStruct * createMyStruct(int length)
{
MyStruct* s = malloc(sizeof(MyStruct));
s->array = malloc(sizeof(char*) * (length + 1));
return s;
}
By the way, usually a struct doesn't have any pointers in it, but only arrays with fixed sizes or at least a char*[] instead of a char* since structs usually have a fixed size to be easier allocable.
If you use my above code don't forget to allocate the char*s the char** refers too since the malloc in my code only allocates the pointers and not the strings itselfes
You could not use MyStruct type to initialize its fields, since they are not static. You have to create struct instance first, initialize it and then - return from your method.
MyStruct * createMyStruct(int length)
{
MyStruct* pResult = malloc(sizeof(MyStruct));
pResult->array = malloc(sizeof(char *) * (length + 1));
return(pResult);
}
Do not forget to free memory after you finish to use it.
PS:
This code is also strange:
pResult->array = malloc(sizeof(char *) * (length + 1));
If you are trying to initialize array of strings of the same length, it is incorrect. You will get an array of length+1, containing uninitialized pointers. If you are simply allocating an array to use its later - then incrementing length is possibly wrong.

Getting seg fault when using malloc with double pointer

I'm using something like this to allocate memory with a function (in C)
void myfunction(struct mystruct** ss) {
// some code
*ss = malloc( 1024 * sizeof (struct mystruct) );
// some code
}
int main()
{
struct mystruct **x;
*x = NULL;
myfunction(x);
return 0;
}
but I'm getting seg fault. What is wrong with this code?
After struct mystruct **x;, the variable x is uninitialized. It is illegal to read from it as your program does in *x = NULL;.
You may have wanted to write:
int main()
{
struct mystruct *x;
x = NULL;
myfunction(&x);
return 0;
}
But it is impossible to be sure, as your program does not do anything meaningful.
Note that x = NULL; is unnecessary anyway: x will be initialized inside myfunction().
you never make any storage for the underlying pointer, there is storage for the ** and the object but not the *...
struct mystruct **x,*y;
x = &y;
myfunction(x);
return 0;

Resources