Reputation: 1753
I have a struct like this:
typedef struct{
size_t length; // length of the array
size_t numbits; // number of bits allocated per val in vals
mpz_t vals[]; // flexible array to hold some number of mpz_t array
} CoolArray;
Ok, so it's a normal flexible array, and I should be able to use malloc to set it's size:
void initArray(CoolArray* array, size_t length, size_t numbits){
assert(length>=1); // don't make arrays with a length<=0
// first I allocate memory for vals...
array->vals = (mpz_t*) malloc(sizeof(CoolArray)+length*sizeof(mpz_t));
// then I allocate memory for each val in vals
mpz_array_init(array->vals, (size_t)length, numbits);
return;
}
but when I try to use this, I get a segmentation fault. I also get complaints about incorrect use of mpz_array_init. But I've looked at the manula, and it seems I am doing this correctly.
I also tried to use my struct like this:
typedef struct{
size_t length; // length of the array
size_t numbits; // number of bits allocated per val in vals
mpz_t* vals; // pointer to start of array
} CoolArray;
and I also changed my initArray
function to this:
void initArray(CoolArray* array, size_t length, size_t numbits) {
assert(length>=1); // don't make arrays with a length<=0
// first I allocate memory for vals...
array->vals = (mpz_t*) calloc(length, sizeof(mpz_t));
// then I allocate memory for each val in vals
mpz_array_init(array->vals, (size_t)length, numbits);
return;
}
This one doesn't segfault, but I get complaints at compile time about
incorrect usage of mpz_array_init
, and I also get a bunch of malloc
errors
in my output, along with the output I want to see. Can anyone tell me where my
code is incorrect? why does the first version segfault? I did it the way
people seem to recommend. And why does the compiler complain about
mpz_array_init
being used incorrectly?
This is the sort of error i get in my output:
gmpascal(80964) malloc: *** error for object 0x100801088: Non-aligned
pointer being freed *** set a breakpoint in malloc_error_break to debug
P.S. gmpascal
is the name of my executable, it computes the nth row of
pascals triangle.
P.P.S. I'm compiling with gcc-4.2
on a Powermac with these flags:
-arch ppc64 -o gmpascal gmpascal.c -lgmp -Wall
Is there something I missing here?
Upvotes: 5
Views: 1655
Reputation: 157314
If you're using a flexible array member, you need to allocate the struct in one go:
CoolArray *array = malloc(sizeof(CoolArray) + length * sizeof(mpz_t));
mpz_array_init(array->vals, length, numbits);
Upvotes: 0
Reputation: 66194
Keep in mind, I do NOT program gmp, but a tail-dynamic buffer in a struct is usually implemented something like this (adapted to how I think you want to use it):
typedef struct
{
size_t length; //length of the array
size_t numbits; //number of bits allocated per val in vals
mpz_t vals[1]; //flexible array to hold some number of mpz_t array
} CoolArray;
Allocation strategy, knowing the the number of values and bit-depth, would be:
CoolArray* allocArray(size_t length, size_t numbits)
{
CoolArray *p = malloc(sizeof(*p) + sizeof(mpz_t)*length);
p->length = length;
p->numbits = numbits;
mpz_array_init(p->vals, length, numbits);
return p;
}
Freeing it (just a wrapper for free(), but you may need to do some gmp-cleanup I'm unfamiliar with):
void freeArray(CoolArray **pp)
{
if (*pp)
{
free(*pp);
*pp = NULL;
}
}
Using it:
CoolArray *pca = allocArray(length, numbits);
Freeing it when done:
freeArray(&pca);
These are just ideas, but maybe you can get something from them.
Upvotes: 3