memory allocation question

T

Trance

I would like to set up a structure that looks like

struct newStruct{

char radius;
char *coreShifts;

}

then have several such structures and access them using pointers. Now,
how can I perform the memory allocation when the number of values in
coreShifts is changing from structure at position 1 vs structure at
position 2, because each structure will occupy different amounts of
memory depending on the number of elements in coreShifts.

Any help or pointing to reading resources would be greatly
appreciated.
Thank you.
 
A

Andy

I would like to set up a structure that looks like

struct newStruct{

char radius;
char *coreShifts;

}

then have several such structures and access them using pointers. Now,
how can I perform the memory allocation when the number of values in
coreShifts is changing from structure at position 1 vs structure at
position 2, because each structure will occupy different amounts of
memory depending on the number of elements in coreShifts.

No. The structure size itself is fixed no matter how much memory you
are going to allocate for char *coreShifts.

struct newStruct var[2];

var[0].coreShifts = malloc(size1);
var[1].coreShifts = malloc(size2);
 
T

Trance

Andy,

Thank you.

So in this case the size of the structure is size of char + size of
pointer data type.

Now, is the reasoning below correct?

struct newStruct *var = NULL;
var = (struct newStruct *)calloc(2,sizeof(struct newStruct));

This just allocates memory for the structure and has nothing to do
with the coreShifts memory allocation. I'm wondering if calloc
initializes the pointers to NULL in the member. For coreShifts, I will
need to allocate memory for those too:

var.coreShifts = (char *) calloc(var.radius,sizeof(char));
(var+1).coreShifts = (char *) calloc((var+1).radius,sizeof(char));


free(var.coreShifts);
free((var+1).coreShifts);
free(var);

because when one frees up the memory one needs to free both the
members of the structure and the structure itself.

Thanks.
 
A

Andy

Andy,

Thank you.

So in this case the size of the structure is size of char + size of
pointer data type.

Not exactly. Becz of alignment..

sizeof (struct newStruct) >= sizeof(char) + sizeof(char *)...
Now, is the reasoning below correct?

struct newStruct *var = NULL;
var = (struct newStruct *)calloc(2,sizeof(struct newStruct));

(struct newStruct *) is not required..

var = calloc(2,sizeof *var); will be a better way to write it..
This just allocates memory for the structure and has nothing to do
with the coreShifts memory allocation. I'm wondering if calloc

Yes... exactly.
initializes the pointers to NULL in the member. For coreShifts, I will

Yes. they do. That is difference it has from malloc()...
need to allocate memory for those too:

var.coreShifts = (char *) calloc(var.radius,sizeof(char));

I think it should be var[0].coreShifts = calloc(var[0].radius, sizeof
*var[0].coreShifts);
(var+1).coreShifts = (char *) calloc((var+1).radius,sizeof(char));

like the one right above...
free(var.coreShifts);
free((var+1).coreShifts);

The same problem as above...
free(var);

because when one frees up the memory one needs to free both the
members of the structure and the structure itself.

Yes. you hit the right point in your case..
 
K

Keith Thompson

Trance said:
Andy,

Thank you.

So in this case the size of the structure is size of char + size of
pointer data type.

Now, is the reasoning below correct?

struct newStruct *var = NULL;
var = (struct newStruct *)calloc(2,sizeof(struct newStruct));

This just allocates memory for the structure and has nothing to do
with the coreShifts memory allocation. I'm wondering if calloc
initializes the pointers to NULL in the member.

calloc sets the allocated memory to all-bits-zero. It's likely to set
pointers to null, but it's not guaranteed, and it's a bad idea to
depend on it.

You might as well just use malloc:

struct newStruct *var;
var = malloc(2 * sizeof *var);
For coreShifts, I will
need to allocate memory for those too:

var.coreShifts = (char *) calloc(var.radius,sizeof(char));
(var+1).coreShifts = (char *) calloc((var+1).radius,sizeof(char));

var[0].coreShifts = malloc(var[0].radius);
var[1].coreShifts = malloc(var[1].radius);

[...]
 
A

Andy

I'll try to rescue you from the mean sorts by getting in here first.
calloc() initializes the pointer objects to all-bits-zero, which
needn't be the null pointer representation.

Thanks for your correction. Han. Yes. It was my mistake...
 
K

Keith Thompson

CBFalconer said:
No problem. coreShifts is an array of pointers,

No, coreShifts is a pointer, not an array of anything.
and when you
allocate a newStruct you will either set coreShifts to NULL or will
allocate (and initialize, probably) the memory needed. The point
is that the contents pointed to by coreShifts should have it's own
internal marker to define its size. Possibly coreShifts points to
strings, which are terminated by a '\0' char.

Possibly coreShifts (more precisely, the coreShifts member of a given
struct newStruct object) points to *a* string, where pointing to a
string is a shorthand for pointing to the first character of a string.
 
C

CBFalconer

Keith said:
No, coreShifts is a pointer, not an array of anything.

A single pointer is an array of one pointer. If the code handles
it as an array it is quite flexible.
 
I

Ian Collins

CBFalconer said:
A single pointer is an array of one pointer. If the code handles
it as an array it is quite flexible.
Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one char*?
 
I

Ian Collins

pete said:
Ian said:
CBFalconer wrote:
Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one char*?

It depends on the context.
For the purposes of pointer math, the answer is "yes".

N869
6.5.6 Additive operators

[#7] For the purposes of these operators, a pointer to a
nonarray object behaves the same as a pointer to the first
element of an array of length one with the type of the
object as its element type.

The important limitation there is "For the purposes of these operators".
 
P

Phil Carmody

Ian Collins said:
pete said:
Ian said:
CBFalconer wrote:
A single pointer is an array of one pointer. If the code handles
it as an array it is quite flexible.

Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one char*?

It depends on the context.
For the purposes of pointer math, the answer is "yes".

N869
6.5.6 Additive operators

[#7] For the purposes of these operators, a pointer to a
nonarray object behaves the same as a pointer to the first
element of an array of length one with the type of the
object as its element type.

The important limitation there is "For the purposes of these operators".

The more important limitation is "a pointer to".

int n;
/*...*/ n /* does not decay into a pointer to a first element */

The answer to your question is clearly 'no'.

Phil
 
K

Keith Thompson

Phil Carmody said:
Ian Collins said:
pete said:
Ian Collins wrote:
CBFalconer wrote:

A single pointer is an array of one pointer. If the code handles
it as an array it is quite flexible.

Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one char*?

It depends on the context.
For the purposes of pointer math, the answer is "yes".

N869
6.5.6 Additive operators

[#7] For the purposes of these operators, a pointer to a
nonarray object behaves the same as a pointer to the first
element of an array of length one with the type of the
object as its element type.

The important limitation there is "For the purposes of these operators".

The more important limitation is "a pointer to".

int n;
/*...*/ n /* does not decay into a pointer to a first element */

The answer to your question is clearly 'no'.

int n;
&n + 1; /* a valid pointer value */

Nobody said that n decays into anything, but n *can* be treated as a
single-element array.
 
P

Phil Carmody

Keith Thompson said:
Phil Carmody said:
Ian Collins said:
pete wrote:
Ian Collins wrote:
CBFalconer wrote:

A single pointer is an array of one pointer. If the code handles
it as an array it is quite flexible.

Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one char*?

It depends on the context.
For the purposes of pointer math, the answer is "yes".

N869
6.5.6 Additive operators

[#7] For the purposes of these operators, a pointer to a
nonarray object behaves the same as a pointer to the first
element of an array of length one with the type of the
object as its element type.

The important limitation there is "For the purposes of these operators".

The more important limitation is "a pointer to".

int n;
/*...*/ n /* does not decay into a pointer to a first element */

The answer to your question is clearly 'no'.

int n;
&n + 1; /* a valid pointer value */

Nobody said that n decays into anything, but n *can* be treated as a
single-element array.

Agreed. In some contexts, such as yours above.

But to get the answer to Ian's question, I think one has to
address what the meaning of "is" is.

I take "is" to be a far stronger than just "can be treated as
the same as in some contexts". "Is" to me means an equivalence
and substitutability. Everything that applies to an array of
one element would have to apply to int n, and that clearly
isn't the case.

And that rests the case for the 'no' faction.

Phil
 
C

CBFalconer

Ian said:
CBFalconer wrote:
.... snip ...


Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one
char*?

They may be. Try:

#define N 10
int *np = NULL; /* one pointer */
int *ptrs[N] = {NULL}; /* array of N pointers */

void foo(int *p) {
/* whatever */
}

int main(void) {
foo(np);
foo(ptrs);
return 0;
}

and tell me how foo can tell how many int* values are passed with
p.
 
P

Phil Carmody

CBFalconer said:
Ian said:
CBFalconer wrote:
... snip ...


Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one
char*?

They may be. Try:

#define N 10
int *np = NULL; /* one pointer */
int *ptrs[N] = {NULL}; /* array of N pointers */

void foo(int *p) {
/* whatever */
}

int main(void) {
foo(np);
foo(ptrs);
return 0;
}

and tell me how foo can tell how many int* values are passed with
p.

None will be passed until the code is actually made to
compile.

Phil
 
C

CBFalconer

Phil said:
CBFalconer said:
Ian said:
CBFalconer wrote:
... snip ...

A single pointer is an array of one pointer. If the code handles
it as an array it is quite flexible.

Oh come on that's bollocks and you know it.

Is "int n;" an array of one int? Is "char* n;" an array of one
char*?

They may be. Try:

#define N 10
int *np = NULL; /* one pointer */
int *ptrs[N] = {NULL}; /* array of N pointers */

void foo(int *p) {
/* whatever */
}

int main(void) {
foo(np);
foo(ptrs);
return 0;
}

and tell me how foo can tell how many int* values are passed with
p.

None will be passed until the code is actually made to compile.

true. But you might get the idea.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top