Adress arithmetic and dynamic arrays

A

Alfonso Morra

Hi,

I'm trying to write a simple generic container. I have the ff:

typedef union {
long int_val ;
char* string_val ;
double dbl_val ;
void* vptr_val ;
}Element ;

I want to be able to store vars of type Element in a dynamic (i.e.
resizable) array . I tried the ff:


#define MAX_NUM 3

int main(int argc, char* argv[]) {

Element* data ;
int i ;

for (i=0;i< MAX_NUM; i++) {
data++ = (Element*)calloc(1, sizeof(int)) ;
*(data) = i ;
}

for (i=0;i< MAX_NUM; i++)
printf("Element %d has value : %d", i,*(data)) ;

for (i=0;i< MAX_NUM; i++)
free(data) ;
}

It is obviously wrong (illegal indirection etc). This is schoolboy stuff
and embarassingly, I've forgotten how to fix it! (using C++ and STL
libraries for too long!).

Any help or pointers (pun intended) much appreciated
 
C

Christopher Benson-Manica

Alfonso Morra said:
typedef union {
long int_val ;
char* string_val ;
double dbl_val ;
void* vptr_val ;
}Element ;

Nothing wrong here...
#define MAX_NUM 3
int main(int argc, char* argv[]) {
Element* data ;
int i ;
for (i=0;i< MAX_NUM; i++) {
data++ = (Element*)calloc(1, sizeof(int)) ;

It's neither necessary nor advisable to cast the return value of
*alloc in this language (forgivable since you've become used to doing
it in C++, from the sound of it).
*(data) = i ;
}

What you really wanted was something like

/* Allocate enough space for MAX_NUM Elements */

data=malloc( MAX_NUM * sizeof *data ); /* check for NULL */
for( i=0; i < MAX_NUM; i++ ) {
data.int_val=i;
}

sizeof Element is by no means guaranteed to be sizeof int; an Element
is at least as large as its largest member, which in this case is
most likely not the int_val. Notice also that you must assign to the
int_val member of the union.
for (i=0;i< MAX_NUM; i++)
printf("Element %d has value : %d", i,*(data)) ;


printf( "Element %d has value: %ld\n", i, data.int_val );
for (i=0;i< MAX_NUM; i++)
free(data) ;


free( data );

I hope that helped.
 
A

Alfonso Morra

Christopher said:
typedef union {
long int_val ;
char* string_val ;
double dbl_val ;
void* vptr_val ;
}Element ;


Nothing wrong here...

#define MAX_NUM 3

int main(int argc, char* argv[]) {

Element* data ;
int i ;

for (i=0;i< MAX_NUM; i++) {
data++ = (Element*)calloc(1, sizeof(int)) ;


It's neither necessary nor advisable to cast the return value of
*alloc in this language (forgivable since you've become used to doing
it in C++, from the sound of it).

*(data) = i ;
}


What you really wanted was something like

/* Allocate enough space for MAX_NUM Elements */

data=malloc( MAX_NUM * sizeof *data ); /* check for NULL */
for( i=0; i < MAX_NUM; i++ ) {
data.int_val=i;
}

sizeof Element is by no means guaranteed to be sizeof int; an Element
is at least as large as its largest member, which in this case is
most likely not the int_val. Notice also that you must assign to the
int_val member of the union.

for (i=0;i< MAX_NUM; i++)
printf("Element %d has value : %d", i,*(data)) ;



printf( "Element %d has value: %ld\n", i, data.int_val );

for (i=0;i< MAX_NUM; i++)
free(data) ;



free( data );



I hope that helped.

Thanks Christopher
 
B

Barry Schwarz

Hi,

I'm trying to write a simple generic container. I have the ff:

typedef union {
long int_val ;
char* string_val ;
double dbl_val ;
void* vptr_val ;
}Element ;

I want to be able to store vars of type Element in a dynamic (i.e.
resizable) array . I tried the ff:


#define MAX_NUM 3

int main(int argc, char* argv[]) {

Element* data ;

At this point, data is uninitialized.
int i ;

for (i=0;i< MAX_NUM; i++) {
data++ = (Element*)calloc(1, sizeof(int)) ;

First a syntax error. data++ is not a modifiable lvalue and so may
not appear on the left of an assignment.

If it could, you would be invoking undefined behavior. Since data is
uninitialized, you cannot increment it.

And finally a "style" issue. Casting the return from calloc rarely
helps but it does cause the compiler to suppress some important
diagnostics if you forget to place a prototype in scope.
*(data) = i ;

Another syntax error. data is a pointer to union. *data is an actual
union. i is an int. You cannot assign an int to a union. You must
assign the value to one of the members of the union, in this case
either int_val or dbl_val.
}

for (i=0;i< MAX_NUM; i++)
printf("Element %d has value : %d", i,*(data)) ;


data is a pointer to union. data is the i-th union pointed to. The
dereference operator is defined to work only on pointers. data is
not a pointer but an actual union.
for (i=0;i< MAX_NUM; i++)
free(data) ;
}

It is obviously wrong (illegal indirection etc). This is schoolboy stuff
and embarassingly, I've forgotten how to fix it! (using C++ and STL
libraries for too long!).

Any help or pointers (pun intended) much appreciated


I think you want data to be a pointer to some number of pointers to
union. Then you want to allocate space for data to point to. Then
you want to allocate space for each pointer in the space to point to.
This last allocation will create space for each of the unions.


<<Remove the del for email>>
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top