I want to get work this code and I googled and asked in efnet and freenode but I didn't find the answer.
What I want is to assign a struct woot to an another bidimensional struct woot *, and I need malloc to do that.
Then, how can I use malloc there and how to assign the struct? Thanks.
#include <stdio.h>
struct omg {
int foo;
};
struct woot {
struct omg *localfoo;
int foo;
};
int a = sizeof(struct woot);
int main(void){
struct woot *what[10][10] = (struct woot *) malloc(100*a);
struct omg hahaha[100];
hahaha[1].foo = 15;
what[1][6].localfoo = &hahaha[1];
}
struct woot *what[10][10] = (struct woot *) malloc(100*a);
I'm curious, does this code even compile? (edit: no, it doesn't.) In any case:
You don't really need malloc() here, declaring struct woot *what[10][10]; should be enough.
Typecasting the returned void* pointer when calling malloc() is unneeded in C (and considered as bad form).
(Not really an answer, I know... I would post it as a simple comment but I don't have enough points yet.)
edit: Oops, others have pointed out the same while I was writing this post.
new edit: Here is a better version of your code, with some mistakes corrected:
#include <stdio.h>
#include <stdlib.h> // needed for malloc()
struct omg {
int foo;
};
struct woot {
struct omg *localfoo;
int foo;
};
int main(void){
const int a = sizeof(struct woot); /* there is no reason "a" should be global...
actually, "a" is not needed at all, and, even if it
were needed, it should be declared as "const" :) */
struct woot *what[10][10];
struct omg hahaha[100];
hahaha[1].foo = 15;
what[1][6]->localfoo = &hahaha[1];
what[7][2] = malloc(a); // I would write "malloc(sizeof(struct woot))"
return 0; // main() should return an int, as declared!
}
You're trying to initialize an array with a scalar value (the pointer returned by malloc). If you really want a 10 by 10 matrix of pointers to structs (and not a 10 by 10 matrix of structs), you don't need malloc:
//Statically allocated 10x10 matrix of pointers, no need for malloc.
struct woot *what[10][10];
To assign a pointer to a cell in that matrix:
struct woot oneSpecificWoot;
what[1][2] = &oneSpecificWoot;
If this is really, really what you want, you could then create a bunch of woots dynamically an populate it. Something like this:
int i, j;
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
what[i][j] = malloc(sizeof(struct woot));
//Of course, you should always test the return value of malloc to make sure
// it's not NULL.
}
}
But if you're going to do that, you might as well just statically allocate the woots themselves:
//A 10x10 matrix of woots, no malloc required.
struct woot what[10][10];
The first case (a 2-D array of pointers) would be more likely if the woots are being created somewhere else, and you just want references to them in a grid lay out, or possibly if you don't know the dimensions of the grid at compile time. But in your code, you're using malloc to create a fixed number of them, so you might as well just have the compiler allocate them statically.
Related
So what i want to achieve is global variable which represents pointer to dynamic array of structs which has other pointers to dynamic arrays inside.
So i've declared everything in the header file like that:
/*** "GLOB.h" ***/
//Dynamic Array of fixed Arrays of 4 floats each
typedef float DArray1[][4];
//Dynamic Array of Integers
typedef int DArray2[];
//Struct
struct MyStruct
{
//pointer to DArray1
DArray1 * A1;
//pointer to DArray2
DArray2 * A2;
//Length of A1 and A2
int len = 1;
//Some other simple elements of fixed size
};
//Dynamic Array of Structs
typedef MyStruct DAStructs[];
namespace GLOB
{
//pointer to DAStructs
extern DAStructs * SS;
//Few other simple variables initialized in place
};
Because i don't rly sure if i declared everything properly - first question is: how to declare such data-structure in C/C++?
And second(+third) is: how to properly initialize and finalize it with some variable length?
I guess initialization and finalization should be something like that:
#include "GLOB.h"
namespace GLOB
{
void Init_SS(int len) {
SS = new MyStruct*[len];
for(int k=0; k<len; k++){
SS[k].A1 = new float*[1][4];
for(int j=0; j<4; j++) SS[k].A1[0][j] = 0.0;
SS[k].A2 = new int*[1];
SS[k].A2[0] = 0;
}
}
void Fin_SS() {
int len = length(SS);
for(int k=0; k<len; k++){
delete [] SS[k].A1;
delete [] SS[k].A2;
}
delete [] SS;
}
}
But obviously it's just a mess of nonsense and not the appropriate code...
P.S. i'd rather avoid using or any other solutions cuz i want to learn first of all and second i need as much control over how elements will be placed in memory as possible cuz later i'll need to pass pointer to such structure to other functions imported from DLLs...
Well nobody answered, but actually the answer was really simple, cuz i did everything almost properly =)
My first (and main) mistake was that i forgot that arrays in C are just pointers to first elements, so instead of
typedef float DArray1[][4];
typedef int DArray2[];
typedef MyStruct DAStructs[];
it should be
typedef float (*DArray1)[4];
typedef int * DArray2;
typedef MyStruct * DAStructs;
And it's not needed to make pointer to array, cuz array is already pointer lol
And my second mistake was that i forgot (well it's not like i knew it =) that length of array in C not stored anywhere, so instead of length(SS) it should be another variable where length should be stored manually upon allocation.
But the whole logic which i assumed seem to be legit, and it works fine. Even tho i didn't tested my project for memory leaks, when i use finalization procedure it seem to free allocated memory without any problems...
When I use code like this :
typedef struct {
int x;
int *pInt;
} tData;
tData *ptData = malloc(sizeof(tData));
If i understand it right, i allocated memory with size of tData and returned adress to this allocated memory to pointer *ptData.
But what if i used this code :
typedef struct {
int x;
int *pInt;
} *tData;
If I want to allocate memory to this struct, do I need a struct name? Because for me, if I allocate like malloc(sizeof(*tData));, it seems to me like I am allocating memory only for the pointer, not for the structure itself. When I want to refer to data in this structure, do I need to use pointer to pointer to a struct?
It confuses me a bit and I couldn't find the answer I am looking for.
Thank you for any explanation!
This is one of the reason one should avoid creating type-aliases of pointers.
As for how to use it, instead of passing the type to the sizeof operator, use the variable. Like e.g.
typedef struct {
int x;
int *pInt;
} *tData;
tData ptData = malloc(sizeof *ptData); // Allocate memory for one structure
I have this struct
struct FluxCapacitor{
unsigned char* c_string;
unsigned int value;
};
Now I need to create an instance of this struct. I googled this problem and found that I have to use something like this
typedef struct FluxCapacitor{
unsigned char* c_string
unsigned int value;
};
But I dont really understand the next step with malloc(). Can someone explain it to me?
You do not need malloc() to create an instance of a struct. And I would recommend that you avoid typedefing structures merely to reduce keystrokes. The extra keystrokes would only be saved in declarations and function prototypes (and maybe if you need to cast something), since you don't need the struct keyword elsewhere; the advantage is that when you see struct FluxCapacitor, you know exactly what it is. If you only see FluxCapacitor alone, you don't know if it is a typedef for a struct, or a union, or an integer type or what.
Note that the posted code was missing the semicolon at the end of the declaration. Also, it is unclear why you have unsigned char* c_string;. This may not allow assignment to a string literal. I have changed this in the code below. You can create a single struct like this:
struct FluxCapacitor
{
char *c_string;
unsigned int value;
};
...
struct FluxCapacitor fcap_1;
You can then assign values to the fields of fcap_1:
fcap_1.c_string = "McFly";
fcap_1.value = 42;
Note that you could also use designated initializers at the point of declaration:
struct FluxCapacitor fcap_2 = { .c_string = "Biff",
.value = 1985
};
If you need an array of FluxCapacitor structures, just declare one:
struct FluxCapacitor fcaps[2];
You can assign to the fields of each array member in a loop:
struct FluxCapacitor fcaps[2];
char *somestrings[] = { "McFly", "Biff" };
unsigned somevalues[] = { 42, 1985 };
for (size_t i = 0; i < 2; i++) {
fcaps[i].c_string = somestrings[i];
fcaps[i].value = somevalues[i];
}
Alternatively, you can use designated initializers here too:
struct FluxCapacitor fcaps[2] = { { .c_string = "McFly", .value = 42 },
{ .c_string = "Biff", .value = 1985}
};
Using malloc()
Since OP seems determined to use malloc(), it would be good to first recall that memory allocated with malloc() must later be deallocated with free(). Also note that malloc() can fail to allocate memory, returning a null pointer. Thus the result of a call to malloc() must be checked before attempting to dereference this pointer. The additional complexity should be avoided in favor of the above approaches unless OP has good reason to do manual allocation.
In the code below, the function create_flux_cap() takes a string and an unsigned int as arguments, and returns a pointer to a newly allocated FluxCapacitor structure with the arguments assigned to the appropriate fields. Note that since the FluxCapacitor structure is accessed through a pointer, the arrow operator is used instead of the dot operator.
Inside the function, the return value from the call to malloc() is checked before attempting assignment. If the allocation has failed, no assignment is made and a null pointer is returned to the calling function. Note that in the call to malloc(), the result is not cast, since there is no need for this in C and it needlessly clutters the code. Also observe that an identifier is used instead of an explicit type with the sizeof operator. This is less error-prone, easier to maintain if types change in the future, and is much cleaner code. That is, instead of this:
new_fcap = (struct FluxCapacitor *)malloc(sizeof (struct FluxCapacitor));
use this:
new_fcap = malloc(sizeof *new_fcap);
In main(), the return values from the calls to create_flux_cap() are checked. If an allocation has failed, the program exits with an error message.
The stdlib.h header file has been included for the function prototypes of malloc() and exit(), and also for the macro EXIT_FAILURE.
#include <stdio.h>
#include <stdlib.h>
struct FluxCapacitor
{
char* c_string;
unsigned value;
};
struct FluxCapacitor * create_flux_cap(char *, unsigned);
int main(void)
{
struct FluxCapacitor *fcap_1 = create_flux_cap("McFly", 42);
struct FluxCapacitor *fcap_2 = create_flux_cap("Biff", 1985);
/* Check for allocation errors */
if (fcap_1 == NULL || fcap_2 == NULL) {
fprintf(stderr, "Unable to create FluxCapacitor\n");
exit(EXIT_FAILURE);
}
/* Display contents of structures */
printf("%s, %u\n", fcap_1->c_string, fcap_1->value);
printf("%s, %u\n", fcap_2->c_string, fcap_2->value);
/* Free allocated memory */
free(fcap_1);
free(fcap_2);
return 0;
}
struct FluxCapacitor * create_flux_cap(char *str, unsigned val)
{
struct FluxCapacitor *new_fcap;
new_fcap = malloc(sizeof *new_fcap);
if (new_fcap != NULL) {
new_fcap->c_string = str;
new_fcap->value = val;
}
return new_fcap;
}
You need malloc for dynamic allocation of memory.In your case, both the types char and int are known to the compiler, it means the compiler can know the exact memory requirement at compile time.
For e.g. you can create a struct object like in the main function
#include<stdio.h>
#include<stdlib.h>
struct FluxCapacitor{
unsigned char* c_string;
unsigned int value;
};
int main() {
FluxCapacitor x;
x.c_string = "This is x capacitor"
x.value = 10
}
The x is of value type. You can make a copy and pass around this value. Also, observe we are using . notation to access its member variables.
But this doesn't happen at all time. We are not aware of future FluxCapacitor requirement and so above program will need more memory as while it is running and by using the malloc we can ask the compiler to provide us requested memory. This is a good place to use malloc, what malloc does is, it returns us a pointer to a piece of memory of the requested size. It is dynamic memory allocation.
Here's a simple example: let suppose if you need struct declaration of FluxCapacitor but don't know how many you will need, then use malloc
#include<stdio.h>
#include<stdlib.h>
typedef struct FluxCapacitor {
unsigned char* c_string;
int value;;
} flux;
// typedef is used to have the alias for the struct FluxCapacitor as flux
int main() {
flux *a = malloc(sizeof(flux)); // piece of memory requested
a -> c_string = "Hello World"; // Pointer notation
a -> value = 5;
free(a); // you need to handle freeing of memory
return 0;
}
.
I just wanted to know if the following works. I have a struct
called foo that is defined as the following:
struct foo {
char name[255];
int amount;
};
During runtime, I need to create an array of the above structures whose size is dependent on a value I receive from a file's input. Let's say this size is k. Will the following code appropriately allocate a dynamically-sized array of structures?
struct foo *fooarray;
fooarray = malloc(k * sizeof(struct foo));
EDIT: If I want to access members of the structures within these arrays, will I use the format fooarray[someindex].member?
That will work (and your accessing is correct). Also, you can guard against size errors by using the idiom:
fooarray = malloc(k * sizeof *fooarray);
Consider using calloc if it would be nice for your items to start out with zero amounts and blank strings, instead of garbage.
However, this is not a VLA. It's a dynamically-allocated array. A VLA would be:
struct foo fooarray[k];
Yes it will.
On failure it will return 0.
And you have to free the memory returned by malloc when you are done with it
You can access the first member:
fooarray[0].name
fooarray[0].amount
The second as:
fooarray[1].name
fooarray[1].amount
etc..
One more different notation can be used in this approach:
struct foo {
char name[255];
int amount;
};
int main (void)
{
struct foo *fooarray;
struct foo *fooptr[5];
unsigned int i = 0;
for (i = 0; i < 5; i++)
fooptr[i] = malloc(1* sizeof(struct foo));
fooptr[2]->name[3] = 'A';
printf ("\nfooptr[2]->name[3]=%c\n",fooptr[2]->name[3]);
}
Is this the correct way to allocate memory for a c struct that contains a dynamic array? In particular, is the way I allocate memory for myStruct correct, considering that it is not yet known how big the struct actually is?
//test.h
struct Test;
struct Test * testCreate();
void testDestroy(struct Test *);
void testSet(struct Test *, int);
//test.c
#include <stdlib.h>
struct Test{
double *var;
};
struct Test * testCreate(int size){
struct Test *myTest = (struct Test *) malloc(sizeof(struct Test));
myTest->var = malloc(sizeof(double)*size);
return(myTest);
}
void testDestroy(struct Test * myTest){
free(myTest->var);
free(myTest);
}
void testSet(struct Test * myTest, int size){
int i;
for (i=0;i<size;++i){
myTest->var[i] = i;
}
}
structs have fixed size, and that's what sizeof returns.
Your struct has on element, a double pointer, and that has a (platform dependent) fixed size.
Your testCreate function does things correctly. In case you don't know the size of the dynamically allocated part, you can set the pointer to NULL to denote that the memory has to be allocated later.
Yes, you correctly malloc space for the struct and then space for the array of doubles in the struct. As a practical matter, you should always test the return from malloc() for NULL before attempting to use the memory. Also, most programs like this store the size of the array in the struct as well so you can write more general code that ensures it doesn't run off the end of the allocated space.