I'm trying to create an array of pointers in C. Each value of the array should be a pointer to a struct (let's call it struct Type*).
Should i do
struct Type* myVariable= malloc(sizeof(struct Type*)*MY_SIZE);
or
struct Type** myVariable= malloc(sizeof(struct Type*)*MY_SIZE);
The second one looks like what i should do when i want to create a two dimensional array, which are an array of pointer, and those pointers are used to create arrays of the wanted type.
EDIT : But in my case the second dimension size would be only one
The first one looks like a regular array with int* as the contained values type.
How can i pass the good solution to a function (by pointer, not by value because the array may be fairly large) and use it in the fonction ?
The second one the right solution. However, you'll need to allocate memory for the objects too. Also, make sure to check the value returned by malloc.
// Allocate memory for the array of pointers.
struct Type** myVariable = malloc(sizeof(struct Type*)*MY_SIZE);
if ( myVariable == NULL )
{
// Deal with error
exit(1);
}
for (int i = 0; i < MY_SIZE; ++i )
{
// Allocate memory for the array of objects.
myVariable[i] = malloc(sizeof(struct Type)*THE_SIZE_IN_THE_OTHER_DIMENSION);
if ( myVariable[i] == NULL )
{
// Free everything that was allocated so far
for (int j = 0; j < i-1; ++j )
{
free(myVariable[j]);
}
free(myVariable);
// Exit the program.
exit(1);
}
}
However, if THE_SIZE_IN_THE_OTHER_DIMENSION is going to be 1, you are better off using your first approach.
struct Type* myVariable = malloc(sizeof(struct Type)*MY_SIZE);
// ^^^^^^^^^^^ Drop the *
if ( myVariable == NULL )
{
// Deal with error
exit(1);
}
Neither!
Use an idiom that reduces work and errors
pointer = malloc(sizeof *pointer * Number_of_elements);
Or in OP's case "to create an array of pointers in C"
#define ARRAY_N 100
struct Type **myVariable = malloc(sizeof *myVariable * N);
if (myVariable == NULL) Handle_OutOfMemmory();
Now set those pointers to some value
#define M 50
size_t i;
for (i=0; i<N; i++) {
myVariable[i] = malloc(sizeof *(myVariable[i]) * M);
if (myVariable[i] == NULL) Handle_OutOfMemmory();
for (size_t m = 0; m<M; m++) {
// Initialize the fields of
myVariable[i][m].start = 0;
myVariable[i][m].value = 0.0;
myVariable[i][m].set = NULL;
}
}
Related
I've created this struct, and a function that initializes all of the fields within that struct and returns a struct pointer. Within this struct I have one single dimensional array of integers, and a two dimensional array of pointers. However, when initialing and incrementing the value inside the cells inside party->fragment_sizes[I] (single dimensional array), party->fragment_sizes[] also begins to increment (two dimensional array). Party->fragment_sizes[i] goes from NULL (0x0) to (0x10000), (0x2000000) I have no idea how, but it's messing me up pretty badly. I need party_fragments_sizes to remain NULL until allocated (inside another function).
#include <stdio.h>
#include <stdlib.h>
typedef struct LonelyPartyArray
{
int **fragments; // the address of fragments[i] is being set as
int *fragment_sizes; // the value inside fragment_sizes[i]
} LonelyPartyArray;
LonelyPartyArray *createParty(int num_fragments)
{
int i;
// Allocating LonelyPartyArray struct pointer
LonelyPartyArray *party = malloc(sizeof(LonelyPartyArray));
// I am allocating these separately,
// is something going on with how my system is
// allocating space for these arrays?
// Allocating LonelyPartyArray
party->fragments = malloc(sizeof(int *) * num_fragments);
// Allocating LonelyPartyArray fragment size
party->fragment_sizes = malloc(sizeof(int) * num_fragments);
// Initializing party->fragments to NULL (not used) and fragment_sizes to zero
for (i = 0; i < num_fragments; i++)
party->fragments[i] = NULL;
for (i = 0; i < num_fragments; i++)
party->fragment_sizes[i] = 0;
// Party->fragments[I] is not remaining NULL, but is being
// incremented. (I.e., party-fragments[I] increments 0x0,
// 0x10000, 0x20000, 0x30000 etc). This needs to remain NULL.
for (i = 0; i < num_fragments; i++)
{
if (party->fragments[i] != party->fragment_sizes[i])
break;
printf("Why is this happening???? [%d]\n", i);
printf("%p\n, party->fragments[i]);
}
return NULL;
}
int main(void)
{
LonelyPartyArray *party = createParty(3);
return 0;
}
I have no idea how party->fragments[] is being set as the address for party->fragment_sizes[], but I need them to be separate.
I have been given a .o file which creates a box_t ** and I have to use it.
Now, I don't know if it is
case 1:
an pointer to an array of box_t or
case 2:
an pointer to an array of box_t *
I wrote a simple code myself in creating box_t** in both the ways and accessed differently. It seems to be working fine in both the cases.
Now, given a box_t **, and size_t n, number of elements in it, is it possible to know if it is case 1 or case 2 without any further information.
struct box_tag{
int pencils;
int pens;
};
typedef struct box_tag box_t;
box_t boxarray[10] = {{1,2},{3,4},
{5,6},{7,8},
{9,10},{11,12},
{13,14},{15,16},
{17,18},{19,20}};
box_t ** box_bundle;
Creation Version1:
box_t** create_dp(void)
{
box_bundle = (box_t **)malloc(sizeof(box_t **));
*box_bundle = boxarray;
}
Accessing Version 1:
int main ()
{
box_t * tmp = *box_bundle;
for (int i =0; i<10; i++)
{
printf("%d\n",tmp[i].pencils);
}
return 0;
}
Creation Version 2:
box_t** create_dp (void)
{
box_bundle = (box_t **)malloc(sizeof(box_t **));
*box_bundle = (box_t *)malloc (sizeof(box_t *) * 10);
for(int i=0; i<10;i++)
{
*(box_bundle +i ) = &boxarray[i];
}
}
Accessing Version 2:
int main ()
{
create_dp();
for(int i=0; i<10; i++)
{
box_t * tmp =*box_bundle++;
printf("pencils %d \n", tmp->pencils);
}
return 0;
}
Both cases are incorrect. You can't use a box_t** to point at any array. Nor can it point to an array of type box_t boxarray[10], because they are incompatible types. There is no need for several levels of indirection anywhere in your code.
You can however use a box_t* to point at the first element in an array, and that's what your code does here: *box_bundle = boxarray;. But in an obfuscated way.
Correct code should be: box_t* box_bundle;. If it should point at the original array, there is no need for malloc. If it should hold a copy of the original array, you need to alloc and copy the data:
box_t* box_bundle = malloc (sizeof(*box_bundle)*10);
memcpy(box_bundle, boxarray, sizeof boxarray);
I have the following piece of code:
//length, width, height
typedef struct {
float L, W, H;
} TDim;
//contains details for each geometrical form
typedef struct {
char *id; // each geometrical form has a unique id
float volume;
TDim *dim;
} TForm;
TForm* FormAlloc()
{
TForm *F = (TForm*) malloc(MAX * sizeof(TForm));
F->id = (char*) malloc(MAX * sizeof(char));
F->dim = (TDim*) malloc(MAX * sizeof(TDim));
return F;
}
which is a good exercise of manipulating variables and pointers within more structures.
What I want to do, is to store the id (basically the letter 'F' followed by 1,2,3...), length, width and height of some rectangular cuboid in order to compute its volume.
I need some explanation around the usage of -> vs .
I understand that -> works with addresses and . with members.
In int main(), I have:
F[0].id = "F1"; //the first cuboid has the id "F1"
F[0].dim[0].L = 1; //the first cuboid has length = 11
//could have used F[0].dim->L = 1; as well?
F[0].dim[0].W = 2;
F[0].dim[0].H = 3;
F[1].id = "F2"; //the second cuboid has the id "F2"
F[1].dim[1].L = 4; //this is where it breaks down - SEG_FAULT (I've used gdb to catch it)
What causes the SEG_FAULT in that line?
In this function:
TForm* FormAlloc()
{
TForm *F = (TForm*) malloc(MAX * sizeof(TForm));
F->id = (char*) malloc(MAX * sizeof(char));
F->dim = (TDim*) malloc(MAX * sizeof(TDim));
return F;
}
you create a dynamic array of MAX elements of TForm, but then you only allocate memory for the id and dim members of the first, hence the segfault when you try to store memory in the second element.
You'll need something like:
TForm* FormAlloc(void)
{
TForm *F = malloc(MAX * sizeof(TForm));
if ( !F ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
for ( size_t i = 0; i < MAX; ++i ) {
if ( (F[i].id = malloc(MAX)) == NULL ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
if ( (F[i].dim = malloc(MAX * sizeof(TDim))) == NULL ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
}
return F;
}
Most likely, you don't want to use MAX for all three purposes, here, i.e. the chances you need exactly the same number of elements of TForm as you need characters in each id string is probably low.
Other more minor points:
malloc() can return NULL, and you should check for that.
In the code in your question, F[0].id = "F1"; should be strcpy(F[0].id, "F1"); or similar, since otherwise you're going to lose your reference to the memory you malloc()ed.
You don't need to, and really shouldn't, cast the return from malloc() in C.
sizeof(char) is always 1 by definition, so you can leave it out.
For the question in your comment:
What about F[0].dim[0].L = 1; vs F[0].dim->L = 1;?
the two are equivalent, here. Using the subscript operator, dim[0], automatically dereferences dim for you, so you'd use the . operator to get at the elements (dim[n] is equivalent to *(dim + n) in C). Without the [0], dim is a straight pointer, so you'd use the -> operator. Obviously the first form is much more convenient when you want to access the other elements in the array. For the others, you'd have to replace F[0].dim[1].L = 1; with (F[0].dim + 1)->L = 1; or similar, to use the -> operator, which is unnecessarily convoluted.
Basically I have two structs and I want to make an array of A structs, and within each A struct I want an array of 50 B structs. So I assume that we will use double pointers.
struct A{
char* a_word;
struct B** b_list;
};
struct B{
char* b_word;
int b_value;
};
When call initialize function I initialize the structs like this. My goal is to set all the values to NULL when I allocate memory.
struct Word** initialize()
{
int k;
int i;
struct A** A_list = calloc(BUFFSIZE, sizeof(struct A*));
for(k =0; k < BUFFSIZE; k++)
{
A_list[k] = calloc (1, sizeof(struct A));
A_list[k]-> b_list = calloc(50, sizeof(struct B*));
for(i = 0; i < 50; i++)
{
A_list[k]->b_list[i] = calloc(1, sizeof(struct B));
}
}
return hashTable;
}
after initializing all these values I am able to do. . .
if(A[43]->a_word == NULL) //43 unallocated value
{
printf("This is null\n");
//program prints this statement - good
//program knows that this value is NULL
}
But I also want . .
if(A_list[44]->b_list[0] == NULL)
{
printf("This is also null");
//This should be printed but nothing happens
}
For some reason not matter if I set the above if statement to == NULL or != NULL the program outputs absolutely nothing from that if statement. What is going on in memory and how can I allocate everything correctly, and so the value is set to NULL as a default and so I can input a value?
EDIT: Also whenever try to do A_list[value1]->b_list[value2] = strdup("string"); I get a segmentation error, this most likely stems from the same problem.
As mentioned already by WhozCraig in a comment to the question, this code
for(i = 0; i < 50; i++)
{
A_list[k]->b_list[i] = calloc(1, sizeof(struct B));
initialises the first 50 elements of b_list to point to valid memory, that is to be non 0, assuming calloc() never fails. Being that optimistic you better test for those elements being != NULL.
... if I set the above if statement to == NULL or != NULL the program outputs absolutely nothing
The code does not seem to flush stdout here:
if(A_list[44]->b_list[0] == NULL)
{
printf("This is also null");
Change this by adding a final \n:
if(A_list[44]->b_list[0] != NULL)
{
printf("This isn't null\n");
As stdout is line buffered by default, all content will be flushed if a new-line is detected.
I am using the CvPoint2D32f struct of opencv, which is defined as
typedef struct CvPoint2D32f
{
float x; /* x-coordinate, usually zero-based */
float y; /* y-coordinate, usually zero-based */
}
CvPoint2D32f;
I am trying to allocate an array of pointers of these objects as follows, and it is not working. How is this to be accomplished?
CvPoint2D32f *cvpoints[8];
for (i = 0; i < 16; i++)
{
if (i % 2 == 0)
{
(*cvpoints)[i/2].x = float(points[i]); // points is an array of ints.
}
else
{
(*cvpoints)[i/2].y = float(points[i]);
}
}
You have an array of pointers to CvPoint2D32f, not an array of the structs themselves. You have no memory allocated for the actual structures. You have three options:
Change your declaration to CvPoint2D32f cvpoints[8]; so you have all of the structures in an array on the stack.
After you allocate the array for the pointers, add a malloc statement to allocate memory. Example:
CvPoint2D32f *cvpoints[8];
for (i = 0; i < 8; i++)
{
cvpoints[i] = (CvPoint2D32f *)malloc(sizeof(CvPoint2D32f));
}
Use malloc to allocate size for all the structures. Example:
CvPoint2D32f *cvpoints = (CvPoint2D32f *)malloc( 8 * sizeof(CvPoint2D32f));
CvPoint2D32f *cvpoints = (CvPoint2D32f*) malloc(sizeof(struct CvPoint2D32f) * 8);
memset(cvpoints, \0, sizeof(struct CvPoint2D32f) * 8);
for (i = 0; i < 16; i++)
{
if (i % 2 == 0)
{
cvpoints[i/2].x = float(points[i]); // points is an array of ints.
}
else
{
cvpoints[i/2].y = float(points[i]);
}
}
And when you're done with them, you free the memory:
free(cvpoints);
Where do these pointers point to? I guess what you want to do is allocate dynamic memory for the structs, but I don't see any memory allocation in your code. Currently all pointers point to undefined memory, so of course this will fail.
You are just creating the pointers, but you need them to point to something in memory!
Example:
struct CvPoint2D32f *cvpoint = (struct CvPoint2D32f *)malloc(sizeof(struct CvPoint2D32f));
if (cvpoint == NULL) {
//malloc error
}