I realize this is most likely a syntax issue, however, I have a struct:
struct pixel{
int pixel_num;
double lowest_dist;
int centroid;
double * location;
};
and an array of these structs struct pixel * pixel_data[10]
and a method: void foo(double ** arr) and am trying to pass the address of the location pointer in an instance of the struct to update the pointer in the method foo.
I attempted to pass it like so foo(&(pixel_data[0]->location)) however this is clearly not correct as when I run through gdb the *arr values are different in foo than what they were in main() where I call foo.
Thanks.
An Example:
#define DIMENSIONS 5
//Struct is declared in header.
//max 10 pixels
struct pixel * pixel_data[10];
int main(){
double newLoc[DIMENSIONS]={1.1,2.2,3.3,4.4, 5.5};
pixel_data[0]=add_pixel(newLoc);
update_centroid_location(&(pixel_data[0]->location), 0, DIMENSIONS);
}
void update_centroid_location(double **centroid, int centroid_num, int numpix){
double * old_cent=malloc(DIMENSIONS*sizeof(double));
if(!old_cent){
perror("couldnt allocate memory");
exit(4);
}
for(int i=0;i<DIMENSIONS;i++){
old_cent[i]=*centroid[i]; //segfaults here as cannot access memory address
}
}
struct pixel * add_pixel(double * location){
struct pixel * new=malloc(sizeof(struct pixel));
if(!new){
perror("Could not allocate space for pixel");
exit(4);
}
new->lowest_dist=DBL_MAX;
new->centroid=0;
new->location=location;
return new;
}
In the line old_cent[i]=*centroid[i]; there is a misunderstanding about operator precedence.
The * operator has a lower precedence than the [].
So you are essentially doing old_cent[i]=*(centroid[i]);
Try to use parenthesis to explicitly express that you want to first dereference then add the offset for the second dereference like so:
old_cent[i]=(*centroid)[i];
Related
I have a series of structs that all have some relatively verbose initialization logic and am trying to refactor that out into a helper function so I don't have to keep writing it over and over. Here's a condensed version:
struct base
{
const int *i;
}
struct child1
{
struct base b;
int j;
}
struct child2
{
struct base b;
int k;
}
void *alloc_base_holder(const int *i, size_t size)
{
struct base b = { i };
void *anon = malloc(size);
// error GD320D622: 'memcpy' forming offset [N1, N2] is out of the bounds [0, N3] of object 'b' with type 'struct base'
return memcpy(anon, &b, size);
}
struct child1 *c1_alloc(const int *i)
{
return (struct child1 *)alloc_base_holder(i, sizeof(struct child1));
}
struct child2 *c2_alloc(const int *i)
{
return (struct child2 *)alloc_base_holder(i, sizeof(struct child2));
}
I'm trying to dynamically allocate and initialize the memory given the size of the struct and not the type, but I'm not sure how to do that.
My first thought was to initialize the base part that is common to all of the child types, and then just memcpy that into a void pointer that had been allocated to the correct size, but that's giving the error:
error GD320D622: 'memcpy' forming offset [N1, N2] is out of the bounds [0, N3] of object 'b' with type 'struct base'
I also had the idea to just manually set the memory of the void pointer (anon), but if that's possible, I haven't come up with the right search terms to find it.
Is this possible to do and can somebody point me in the right direction?
Edit:
I'm using gcc with C99 by the way.
Reason of the warning are explained in the other answer.
I suggest always accessing the object via it's final type (struct child1 or struct child2). Otherwise one may easily trigger UB due to strict aliasing rules.
Therefore it's better to have init_base_holder() rather than alloc_base_holder.
void init_base_holder(struct base *b, const int *i)
{
b->i = i;
}
struct child1 *c1_alloc(const int *i)
{
struct child1 *c = malloc(sizeof *c);
init_base_holder(&c->b, i);
return c;
}
struct child2 *c2_alloc(const int *i)
{
struct child2 *c = malloc(sizeof *c);
init_base_holder(&c->b, i);
return c;
}
You get the "error" because you copy size bytes from the base structure b, even if size > sizeof b (which will go out of bounds of the b structure object).
I recommend that you use calloc instead, to let the allocator zero-initialize the allocated memory.
Then copy only the base structure itself, i.e. sizeof b instead:
memcpy(anon, &b, sizeof b);
Of course, you first need to make sure that size >= sizeof b.
You can just allocate size bytes for an instance of base.
struct base *b = malloc(size);
And then initialize the members as usual.
(Proficient at C++, newbie at C) getting a segfault error from the addArray() call in main(). I've checked many posts and several texts, it compiles, but no luck running it. I'm coding it on VS2015 and all the usual handy cues are there with pointers, etc. Cleary something I'm not aware of or a syntax error. This is the distilled code that reproduces the error.
#include<stdio.h>
#include <stdlib.h>
#define TYPE int
struct arrayHolder {
TYPE data[100];
int count;
};
//prototypes.
void initArray(struct arrayHolder * );
void addArray(struct arrayHolder *, TYPE);
int main() {
struct arrayHolder * myStruct = NULL;
initArray(myStruct);
addArray(myStruct, 123);
}
/* Allocate memory for struct arrayHolder */
void initArray(struct arrayHolder * b) {
b = (struct arrayHolder *)malloc(sizeof(struct arrayHolder));
b->count = 0;
}
/* Add an element to data[] */
void addArray(struct arrayHolder * b, TYPE v) {
int count = b->count;
b->data[count] = v;
(b->count)++;
}
As #def1 observed, you are passing pointers by value. That's not an issue for addArray() -- the problem is with initArray(). That function's parameter is local to the function, so when you assign the malloc()ed pointer to it, the result is not visible in main(). Ultimately, you end up passing a NULL pointer to addArray().
There are at least two possible solutions.
In the code presented, it's not clear to me why the struct arrayholder needs to be dynamically allocated at all. If in main() you declare instead struct arrayholder myStruct; and remove the malloc() call from initArray(), then everything else should work as-is.
Alternatively, if you do need to perform dynamic allocation then either you should return a pointer to the allocated memory from initArray() (in which case that function does not require a parameter) or else you need to pass a double pointer to the function, so that main()'s pointer can be updated thereby.
The only one of those alternatives that should be at all tricky is the double pointer variant, which would look like this:
int main() {
struct arrayHolder * myStruct = NULL;
initArray(&myStruct); /* difference here */
addArray(myStruct, 123);
}
/* Allocate memory for struct arrayHolder */
void initArray(struct arrayHolder ** b) {
/* no cast is required here in C, and many account one poor style: */:
*b = malloc(sizeof(struct arrayHolder));
(*b)->count = 0;
}
void initArray(struct arrayHolder * b)
Here you pass a pointer to a struct arrayHolder to the function. The pointer is passed by value which means it is a copy. You can change the data the pointer is pointing to but when you assign the result of malloc to b you are modifying the copy of the pointer itself, which will not influence the pointer in main.
Possible solution is to use a pointer to a pointer.
void initArray(struct arrayHolder ** b) {
*b = (struct arrayHolder *)malloc(sizeof(struct arrayHolder));
(*b)->count = 0;
}
I understand the difference between memory allocation using malloc for an array of struct and for an array of pointers to struct. But I want to assign memory using malloc for an array of struct, in the case that the struct itself contains a pointer to another struct. Here is the code for what I am trying to do:
#include<stdio.h>
#include<stdlib.h>
typedef struct linkedlist {
int pCol;
struct linkedlist *next;
} plist;
typedef struct particle {
int color;
double rad;
double rx;
double ry;
double vx;
double vy;
struct linkedlist *event;
} state;
int main()
{
int N = 5, w = 4;
plist *ls = (plist*)malloc((N+w)*sizeof(plist));
printf("N=%d, w=%d, sizeof state=%d, total=%d, sizeof discs=%d\n\n",
N,w,sizeof(plist), (N+w)*sizeof(plist), sizeof(ls));
state *discs = (state*)malloc((N+w)*sizeof(state));
printf("N=%d, w=%d, sizeof state=%d, total=%d, sizeof discs=%d\n",
N,w,sizeof(state), (N+w)*sizeof(state), sizeof(discs));
return 0;
}
When I run this, I get the following output:
N=5, w=4, sizeof plist=8, total=72, sizof ls=4
N=5, w=4, sizeof state=56, total=504, sizof discs=4
So, I want to know why does the ls or the discs get assigned only 4 bytes and how can I get total memory required assigned for these arrays of structs?
You are printing size of pointer(ls) and not size of datatype/structrure pointed by the pointer (*ls).
Do sizeof(*ls) and sizeof(*discs) in your printf statements if you intend to find size of plist and state because that is where ls and discs point to.
If you are thinking of printing the total size allocated to ls or discs by malloc. That is not possible. Its not going to print ((N+w)*sizeof(plist)).
So even doing sizeof(*ls) is not going to tell you how many plist structures you allocated
in your code, ls is of type plist *,.i.e., a pointer.
sizeof() is an operator which returns the size of the data type, not the amount of memory allocated.
Same goes for discs.
I have a struct with an int array inside that I'm passing to a function for the array to be initialized
array struct like so..
typedef struct Container{
struct intArray *P;
int length;
} Container;
typedef struct intArray{
int *array;
int length;
} intArray;
function to initialize the array
like so...
int Initializer(intArray *myStruct, int n)
{
myStruct->array = malloc(sizeof(int) * (lengthOfint);
^
If n=55 then length would be 2
//let's just say n=5
myStruct->array[0] = n;
//return 1 if successful
return 1;
}
In another function I am calling the initializer function like so...
Container *myContainer = malloc(sizeof(Container));
myContainer->P = malloc(sizeof(intArray *) * Some_Defined_Value);
Initializer(&myContainer, 5);
printf("the data that should be at index 0 -> %d\n", myContainer->P.array[0];
I would think that the printf statement would print out 5 but it prints out garbage of varying numbers every time I compile it. I don't think I have a grasp of the array within a struct within a struct idea.
You pass the container to the initializer function, but if you look closely you'll see that the you are passing a pointer to a pointer to the "outer" container instead of a pointer to the desired struct intArray. You'd want something like Initializer(myContainer->P, 5);
Container holds a pointer to struct intArray, which in this case is the start of an array of struct intArray. But then you initialize this pointer with
malloc(sizeof(intArray *) * Some_Defined_Value);
So malloc returns a pointer to a memory space which holds pointers to struct intArray because you used sizeof(intArray *) and not sizeof(intArray) (you allocated space for Some_Defined_Value number of pointers).
You need sizeof(intArray) * Some_Defined_Value here to allocate space for Some_Defined_Value number of struct intArray's.
Then you use
Initializer(&myContainer, 5);
which should at least give a warning because you pass a pointer to a pointer to a struct Container, but Initializer expects a pointer to a struct intArray, so this is not what you want. To initialize the first element of your array of struct intArray's use:
Initializer(&(myContainter->P[0]), 5);
Then:
printf("the data that should be at index 0 -> %d\n", myContainer->P.array[0]));
This code does not compile because it should be:
printf("the data that should be at index 0 -> %d\n", myContainer->P[0].array[0]);
myContainer->P accesses a pointer to a struct intArray. The code right above means you access the first element (element number 0) of the array of struct intArray's .
To initialize/access the second element of the array of struct intArray's use:
Initializer(&(myContainter->P[1]), 5);
printf("the data that should be at index 0 -> %d\n", myContainer->P[1].array[0]);
Also be aware that malloc returns a void * so most of the time you'll need a cast like so:
myStruct->array = (int*)malloc(sizeof(int) * (length);
// ^^^^^^
Assuming length is the number of int you want to store in your array.
Is it a right way to pass a pointer to dynamic array? Is it going to work? If not, explain why, if it does, explain why as well. Thank you.
struct record
{
char * community_name;
double data[10];
double crimes_per_pop;
};
void allocate_struct_array(struct record *** r);
int main()
{
/* allocating pointer to an array of pointers */
struct record ** r;
/* passing its address to a function */
allocate_struct_array( &(**r) );
}
/* function gets an address */
void allocate_struct_array(struct record *** r)
{
...
}
What I was trying to do is to allocate an array of pointers, where each pointer points to structure record. Function suppose to allocate this array using just pointer to r, which was declared in main. Was playing with this code, but cannot make it to work.
I don't know what you are trying to do, but at least you have a programmatic error.
allocate_struct_array( &(**r) );
needs to be -
allocate_struct_array(&r);
In the function interface, you only need a double pointer struct record **r and not a triple pointer.
An array can be represented by a struct record *array; so a pointer to that is struct record **ptr_to_array.
You call the function with &array.
struct record
{
char * community_name;
double data[10];
double crimes_per_pop;
};
void allocate_struct_array(struct record **r);
int main()
{
struct record *r;
allocate_struct_array(&r);
}
void allocate_struct_array(struct record **r)
{
*r = malloc(23 * sizeof(struct record));
...
}