Data structure problem - c

I made a structure like so:
struct ponto {
int x;
int y;
int z;
};
1) Can I initialize the int's with a default value? int var = value; doesn't seem to work, compiler says "syntax error before '=' token" or something of sorts.
2) I need to work with several of these like in a array of structures, but I only know how many I need after the application starts up, after reading a file. How can I malloc this?
Thanks in advance
EDIT: So many answers, I'm grateful. Sadly I can only mark one

a) You can initalise with
struct pronto p = {1,2,3};
In recent compilers (not sure how portable this is, think it's C99?)
b) You can allocate an array with malloc:
struct pronto *array = malloc(sizeof(struct pronto) * NUMBER);

To initialize your structure members to 0, do:
struct ponto foo = { 0 };
To malloc() an array of the right size, do:
struct ponto *arr = (struct ponto *) malloc(COUNT * sizeof(struct ponto));
Don't forget to free() the array when you're done with it.

struct ponto* create_and_init_ponto(int n)
{
struct ponto* array;
int i;
array = (struct ponto*)malloc( n * sizeof(struct ponto) );
for ( i = 0; i < n; ++i )
{
array[ i ].x = 0;
array[ i ].y = 0;
array[ i ].z = 0;
}
return array;
}

You'e made a structure definition, now you have to create a variable of that structure before you can set the fields:
struct ponto xyz;
xyz.x = 7;
To allocate enough space:
int need_to_have = 24;
struct ponto *pontos = malloc (need_to_have * sizeof(struct ponto));

You cannot have "default" values for structure members. Space is not allocated for a structure definition. You're just creating a new type (like the inbuilt int). When you actually define a variable of type ponto, space will be allocated to it.
You can make an educated guess about how many you will need, allocate space for that many (using malloc) and go ahead. If you find that you're reaching the limit, you can use the realloc function to resize your array.

1) You cannot give a specific structure default values for its elements at the language level, because all variables in C are uninitialized unless you explicitly initialize them (or make them static/external in which case they're zero-initialized). If you design your structs such that all-zeros is a good set of initial values, though, you can always initialize like this:
struct foo myfoo = {0};
The {0} serves as a universal zero-initializer which works for any type.
If you need different defaults, the best way is to use a macro and document that code using your structure must use the macro:
#define FOO_INITIALIZER { 1, 2, 3 }
struct foo myfoo = FOO_INITIALIZER;
2) If you know before you start using any of the struct how many you will need, simply malloc them all once you know the number:
if (count > SIZE_MAX / sizeof *bar) abort();
struct foo *bar = malloc(count * sizeof *bar);
Note the proper idiom for calling malloc and avoiding overflow vulnerabilities.
If you don't know the number you'll need until you start working with them, start out by allocating a decent number, and if you run out, increase the number by a fixed multiple, for example doubling the size is common and easy. You'll want to check for overflows here. Then use realloc.

Question #1: If you need to initialize int with a value:
struct ponto p1;
p1.x = p1.y = p1.z = 3; // initializing with three
Alternatively, if you want to initialize all values to 0, you can use memset like this:
memset(&p1, 0, sizeof(struct ponto));
Question #2: To use malloc:
struct ponto *ps;
ps = (struct ponto *)malloc(N*sizeof(struct ponto));
// where N is your element count.
This will allocate memory to store N elements of type struct ponto. After that, you can initialize its values with:
int initvalue = 3; // assuming you want to initialize points with value 3
for (i=0; i<N; i++) {
ps[i].x = ps[i].y = ps[i].z = initvalue;
}

Related

Creating an Array that creates instance of a struct

Hello everyone I got the following struct
struct Test
{
unsigned char* c_string;
unsigned int value;
};
I created a function that creates a new instance of this struct and initialize the attributes with random values like this
struct Test* createNewTest(){
struct Test *NewInstance = (Test * )malloc( sizeof(Test) );
NewInstance->value = rand();
Now I have to create a function that creates n completely initialized instances of my struct.
struct Test** createNewArray(unsigned int n){
};
Can anyone help me to do this? I dont really now how to start here
It's fairly straightforward. First, you'll need to allocate enough storage for n pointers to struct Test:
struct Test **array = malloc(n * sizeof *array);
if (!array) return array;
And then assign each pointer, using the function you have:
for (size_t i = 0; i < n; ++i)
array[i] = createNewTest();
Wrapping it all up, you get
struct Test **createNewArray(size_t n)
{
struct Test **array = malloc(n * sizeof *array);
if (!array) return array;
for (size_t i = 0; i < n; ++i)
array[i] = createNewTest();
return array;
}
Don't forget to write a matching free() function!
Also, consider whether you really want an array of pointers to Test - you may be better off with an array of Test objects instead.
I'm going to try to explain this without giving you the answer to your assignment verbatim ...
First, you need to allocate n times as much memory. malloc can allocate any amount, so you just need to calculate the number.
Second, you need to do the same initialization, but for each entry in the array. You'll need a loop for that.
Hint: in C, a pointer to a single instance and a pointer to a dynamic array are indistinguishable. ptr->value is the same as ptr[0].value, and ptr[1].value is the next element in the array.

How to correctly allocate memory to a dynamic array of integers stored in a struct?

I have a function that sets values to a struct:
My struct:
struct entry {
char key[MAX_KEY];
int* values;
size_t length;
entry* next;
entry* prev;
};
My function:
// Sets entry values
void command_set(char **commands, int arg_num) {
struct entry e;
e.length++;
strcpy(e.key, commands[1]);
for (int i = 2; i < arg_num; i++) {
e.values[i - 2] = atoi(commands[i]);
}
}
where:
**commands: is a array of strings
arg_num: is how many strings are in the array
key: is the name of the entry
values: are integer values store in the entry
I run the code and I get a segmentation fault 11. I have narrowed it down to the line:
e.values[i -2] = atoi(commands[i]);
I assume that I have to use malloc to allocate memory as I don't appear to have gone out of bounds with my loop. I have tried to understand the correct way to allocate memory however I can't seem to get the syntax correct for allocating sizeof(int) to a dynamic array of integers.
I have tried:
e.values[i - 2] = malloc(sizeof(int));
and
e.values[i - 2] = (int) malloc(sizeof(int));
and
e.values[i - 2] = malloc(sizeof(int *));
However I get the error:
incompatible pointer to integer conversion assigning
to 'int' from 'void *' [-Werror,-Wint-conversion]
You must allocate the whole array:
e.values = malloc(sizeof(int) * (arg_num - 2))
Important: Remember to call free when you're done with the memory or you will have a memory leak.
You have another problem though, unrelated to the one you're asking about.
You do
struct entry e;
e.length++;
When the structure object e is defined, it is uninitialized, all its members will have an indeterminate value. Using such uninitialized data in any way except to initialize it will lead to undefined behavior. And you do use such uninitialized values when you do e.length++.
That increase simply doesn't make any sense in the code as you show it. On the other hand, that function doesn't make a lot of sense anyway since the variable e and all its data will simply "disappear" when the function returns. So I can only assume that it's not the complete function you show us.
To initialize the structure to all zeroes, simply do
struct entry e = { 0 };
as your struct is as follows
struct entry {
char key[MAX_KEY];
int* values;
size_t length;
entry* next;
entry* prev;
};
then you should allocate memory to it as
e.values =(int *)malloc(arg_num*sizeof(int));
like if you have 10 values then you are allocating 10*4 values to it.
and invoke free on it
free(e.values)
when the e or e.values is no more useful. for more information you can see here
Modify the function as below.
void command_set(char **commands, int arg_num) {
struct entry e;
e.length++;
strcpy(e.key, commands[1]);
//here is the memory allocation
e.values = malloc(arg_num-1 * sizeof(int));
for (int i = 0; i < arg_num-1; i++) {
e.values[i] = atoi(commands[i+1]);
}
}

allocate dynamic multiple array

Let's say we have the following design:
typedef struct {
double **pdouble;
int *pint
}foo;
now I want to allocate:
foo *pfoo;
the thing is that the total number of pdouble is known, lets say its n; if we say **pdouble is like pdouble [a][b], a is also known. means a*b =n. but b is dynamic. mean pdouble[1] might contain b column and pdouble[2] might have b' number of column, also b and b',b" ... will generate in the program gradually.
its worth noting that b+b'+b"+ ... = n.
is it possible to allocate foo using just knowing n and a?
I'm going to edit it a little so my question will become more understandable.
allocation_func(in size, int block_size)
foo *pfoo;
pfoo = (foo*) malloc(sizeof(foo))
/*some code here to do block_size number of *double which I don't know*/
foo->pdouble = (double**) malloc ( size * sizeof(double))
}
I ignored errors and other required thing which everybody knows.
Thats all;
First allocate struct memory
foo *pfoo = malloc(sizeof *pfoo);
then allocate memory for struct member double **pdouble;
//for example purpose i take 50x50 array
pfoo->pdouble = malloc(50* sizeof(double *));
for(int i=0;i<50;i++)
pfoo->pdouble [i] = malloc(50* sizeof(double ));
And finally allocate memory for struct member int *pint
pfoo->pint=malloc(100*sizeof(int)); //100 is just for example

array of pointers allocation

typedef struct
{
struct table **symbols; // array of the stack
int top; //index of the top element
int size; //maximum size of the stack
}stack;
void *createStack(int size)
{
stack *stck;
stck = (stack *) malloc(sizeof(stack));
stck->symbols = ....
stck->size = size;
stck->top = -1;
printf("stack is created --> size is : %d \n",size);
}
Here I need to allocate my stack's symbol array which is "..." but I couldn't figure out it's syntax, pls help : )
(struct table **)malloc(size * sizeof(struct table*));
But that's if you want to pre-allocate all the space at once. If you want to allocate more as you go, you could start with something smaller than size and allocate more in your push() function when you run out of space.
malloc(size * sizeof(struct table*));
Is symbols intended to be a 1-d array of pointer to struct table or a 2-d array of struct table?
stck->symbols = malloc(sizeof *(stck->symbols) * numberOfElements);
for whatever value of numberOfElements. Given that the type of stck->symbols is struct table **, the type of the expression *(stck->symbols) will be struct table *. You could also write
malloc(sizeof (struct table*) * numberOfElements);
but I prefer the former method, as it minimizes the number of places you have to remember the type.
As this is C, you do not need to cast the result of malloc(), and it's considered poor practice to do so; if you forget to include stdlib.h or otherwise don't have a prototype for malloc() in scope, the cast will supress a warning alerting you to the problem (although since C99 no longer allows implicit int typing, that may no longer be an issue).
stck->symbols = baseaddress = malloc(...required total size...);
int nextDataLocation = baseAddress + numberOfRows*sizeof(void*);
for(int i=0; i<numberOfLines; i++)
{
stck->symbols[i] = nextDataLocation;
..copy string i to address stck->symbols[i]...
nextDataLocation += lengthOfString[i];
}

struct c dynamically allocate memory

I am using a struct and I want to initialize a maximum of 10 ports. However, when the program is running it could be a lot less, we don't know until run-time. However, this will be the max. I have never done struct like this before, as I normally dynamically allocate using calloc and delcare like this *ports as the value type.
However, I can't understand this
*ports[MAX_PORTS]. Am I creating 10 pointers that point to port objects?
And
*ports = (struct port_t*) calloc(2, sizeof(*ports));
Looks like I am allocating a single pointer that points to 2 port objects allocated on the free store?
I can't understand why I am using a dot operator with a arrow operator?
ports[0]->port_id = 20;
printf("port_id: %d\n", ports[0]->port_id);
#include <stdio.h>
#include <stdlib.h>
#define MAX_PORTS 10
struct port_t
{
int port_id;
char name;
} *ports[MAX_PORTS];
int main(void)
{
*ports = (struct port_t*) calloc(2, sizeof(*ports));
ports[0]->port_id = 20;
printf("port_id: %d\n", ports[0]->port_id);
return 0;
}
normally, what I have done in the passed is this:
struct port_t
{
int port_id;
char name;
} *ports;
ports = (struct port_t*) calloc(2, sizeof(*ports));
And then assign with either of the following below. However, the previous programmer has declared everything like I have displayed at the top so I can't change anything.
ports[0].port_id = 10;
ports->port_id = 10;
Many thanks for any suggestions,
Your first code block has
struct port_t
{
int port_id;
char name;
} *ports[MAX_PORTS];
which is an array of pointers. This means later when you use
ports[0]->port_id
you are dereferencing the first pointer in the array. There is also some ugliness surrounding the size of what you are actually calloc'ing. You're actually replacing your array of 10 with an array of 2. What you've got there is generally ugly and error prone.
I believe your intentions are more along the lines of:
struct port_t
{
int port_id;
char name;
} *ports;
int main(void)
{
*ports = (struct port_t*) calloc(2, sizeof(*ports));
ports[0].port_id = 20;
printf("port_id: %d\n", ports[0].port_id);
return 0;
}
Since you are using C99, you could avoid calloc()/malloc(), if you really want to by using C99's variable array declaration.
port_t array_on_mains_stack[some_runtime_port_count];
ports = array_on_mains_stack;
The trick there is that since it is on the stack, it is only valid from that function and any function called by it. Once you return from that function, it is of course freed.
*ports[MAX_PORTS]. Am I creating 10 pointers that point to port objects?
Yes, you're making an array of ten pointers
*ports = (struct port_t*) calloc(2, sizeof(*ports));
...but this line is nonsense. It's the same as this:
ports[0] = (struct port_t*) calloc(2, sizeof(port_t));
ie. You're setting the first pointer to point to enough memory for two ports.
For such a small thing it would make much more sense to make ten ports but not use them all:
#define MAX_PORTS 10
struct port_t
{
int port_id;
char name;
} ports[MAX_PORTS];
/* number of ports in use */
int numPorts = 0;
int main(void)
{
numPorts = 3;
for (int i=0; i<numPorts; i++) {
ports[i].port_id = i;
printf("port_id %d: %d\n", i, ports[i].port_id);
}
return 0;
}
ports is and array of pointers to port_t objects, so by doing ports[0] you get a pointer, not an object, and you need to access it with ->
Grab a good resource on pointers in C and read it from cover to cover. There are also tutorials on reading C declarations. You won't be able to understand this topic by getting answers to random questions.
Here's a link worth reading.

Resources