Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Allocating an array of char* - newbie

Reply
Thread Tools

Allocating an array of char* - newbie

 
 
john
Guest
Posts: n/a
 
      10-26-2004
Hello,
I wrote thsi small program ; I am quite a newbie in this.

#include <stdio.h>
#include <stdlib.h>


typedef struct argsArray
{

char* ip_addresses[];
int no_of_addresses;
} argsArray;


int main()
{
argsArray* argsArrayPtr = (argsArray*)malloc(sizeof (argsArray));
argsArrayPtr->no_of_addresses = 3;
argsArrayPtr->ip_addresses[0]="10.0.0.0";
argsArrayPtr->ip_addresses[1]="10.0.0.1";

printf("no_of_addresses %d\n",argsArrayPtr->no_of_addresses);

printf("argsArrayPtr->ip_addresses[0] = %s\n",argsArrayPtr->ip_addresses[0]);
printf("argsArrayPtr->ip_addresses[1] = %s\n",argsArrayPtr->ip_addresses[1]);

}

this program prints:

no_of_addresses 134514264
argsArrayPtr->ip_addresses[0] = 10.0.0.0
argsArrayPtr->ip_addresses[1] = 10.0.0.1

where no_of_addresses should be 3;
It is obviously a matter of performing malloc() to the ip_addresses[] array;
but what should I exactly do it ? I do not know the sizes of the IP addresses :
they can vary from 7 to 15 characters length .Moreover, I do not know the
number of elements (ip addresses) in that array ; it is filled in run time
from some file. (I do have an upper bound).


regards,
John
 
Reply With Quote
 
 
 
 
Jens.Toerring@physik.fu-berlin.de
Guest
Posts: n/a
 
      10-26-2004
john <(E-Mail Removed)> wrote:
> I wrote thsi small program ; I am quite a newbie in this.


> #include <stdio.h>
> #include <stdlib.h>



> typedef struct argsArray
> {
> char* ip_addresses[];


That's not valid C, you can't create an array of (char pointers) of
indeterminate size. What you will need here is a pointer to pointer
to char and, once you know how many pointers you need, you must
allocate enough for them. So make that

char **ip_addresses;

> int no_of_addresses;
> } argsArray;
>


> int main()
> {
> argsArray* argsArrayPtr = (argsArray*)malloc(sizeof (argsArray));


It usually doesn't make too much sense to cast the return value of
malloc(). The conversion is done automatically for you and the cast
will keep the compiler from warning you if you forget to include
<stdlib.h> where malloc() is declared. Furthermore, you should make
it a habit to always check the return value - if malloc() fails it
returns a NULL pointer. But if you only need one of these structures
it probably would make more sense here to use a real structure here
instead of using a pointer and then allocating memory for it...

> argsArrayPtr->no_of_addresses = 3;
> argsArrayPtr->ip_addresses[0]="10.0.0.0";
> argsArrayPtr->ip_addresses[1]="10.0.0.1";


Before you can do that you need to allocate memory for the pointers.
Do that e.g. by

if ( ( argsArrayPtr->ip_addresses =
malloc( 2 * sizeof *argsArrayPtr->ip_addresses ) )
== NULL ) {
fprintf( stderr, "Running out of memory\n" );
exit( EXIT_FAILURE );
}

If you want not just to assign some addresses of literal strings
(like you do in your example code) but copy strings you also will
have to allocate memory for the strings themselves and assign that
to the char pointers you got from the previous allocation.

> printf("no_of_addresses %d\n",argsArrayPtr->no_of_addresses);
>
> printf("argsArrayPtr->ip_addresses[0] = %s\n",argsArrayPtr->ip_addresses[0]);
> printf("argsArrayPtr->ip_addresses[1] = %s\n",argsArrayPtr->ip_addresses[1]);


> }
>
> this program prints:


> no_of_addresses 134514264
> argsArrayPtr->ip_addresses[0] = 10.0.0.0
> argsArrayPtr->ip_addresses[1] = 10.0.0.1


> where no_of_addresses should be 3;
> It is obviously a matter of performing malloc() to the ip_addresses[] array;
> but what should I exactly do it ? I do not know the sizes of the IP
> addresses: they can vary from 7 to 15 characters length.


Well, first thing you need to do is allocate memory for the pointers
to the strings. Then you have to allocate memory for the strings. If
you don't know how long a string is going to be but have an upper bound
allocate enough memory for the worst case (and don't forget about the
trailing '\0' character!) and, when you find that this was too pessi-
mistic, i.e. you don't need all of it, use realloc() to reduce the size
of the allocated memory.

> Moreover, I do not know the number of elements (ip addresses) in that
> array ; it is filled in run time from some file. (I do have an upper
> bound).


Again, if you have an upper bound you can always start with the worst
case scenario and later get rid of the memory you don't need by using
realloc(). But you can also employ a different strategy: start with a
guess and, if that turns out to be too optimistic, increase the size
by also using realloc(). In the simplest case you could start of with
a pointer for just a single string and, if you find that there's one
more, just increase the size and repeat until you got all of them.
Unless this part of the program is used extremely often the impact one
the performance probably is going to be neglectable. Or start with a
guess, and if that turns out to be too small, double the size and
continue and repeat if necessary. - and when you're finished get rid
of the superfluous memory by a final call of realloc().

Here's some C code mixed with pseudo code using the simplest method,
i.e. increasing the array of char pointers each time you find that
there's still one more IP address to store:

#define MAX_IP_LENGTH 16

int ip_count = 0;

argsArrayPtr->ip_addresses = NULL;

do {
determine if there's another IP address
if ( no_more_IP_addresses )
break;

argsArrayPtr->ip_addresses =
realloc( argsArrayPtr->ip_addresses,
( ip_count + 1 ) * sizeof *argsArrayPtr->ip_addresses );

if ( argsArrayPtr->ip_addresses == NULL ) {
fprintf( stderr, "Running out of memory\n" );
exit( EXIT_FAILURE );
}

argsArrayPtr->ip_addresses[ ip_count ] = malloc( MAX_IP_LENGTH );

if ( argsArrayPtr->ip_addresses[ ip_count ] == NULL ) {
fprintf( stderr, "Running out of memory\n" );
exit( EXIT_FAILURE );
}

store address of new IP address string into 'the_new_ip_address';
strcpy( argsArrayPtr->ip_addresses[ ip_count ], the_new_ip_address );

argsArrayPtr->ip_addresses[ ip_count++ ] =
realloc( argsArrayPtr->ip_addresses[ ip_count ],
strlen( the_new_ip_address ) + 1 );
}

If you want to write that in a way where you are able to recover from
the case that you run out of memory instead of just exit()ing make sure
you store the pointer with the address of the memory you already own
before you call realloc(), otherwise you won't be able to deallocate
it anymore.
Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de
\__________________________ http://www.toerring.de
 
Reply With Quote
 
 
 
 
Neil Kurzman
Guest
Posts: n/a
 
      10-27-2004


john wrote:

> Hello,
> I wrote thsi small program ; I am quite a newbie in this.
>
> #include <stdio.h>
> #include <stdlib.h>
>
> typedef struct argsArray
> {
>
> char* ip_addresses[];
> int no_of_addresses;
> } argsArray;
>
>
> int main()
> {
> argsArray* argsArrayPtr = (argsArray*)malloc(sizeof (argsArray));
> argsArrayPtr->no_of_addresses = 3;
> argsArrayPtr->ip_addresses[0]="10.0.0.0";
> argsArrayPtr->ip_addresses[1]="10.0.0.1";
>
> printf("no_of_addresses %d\n",argsArrayPtr->no_of_addresses);
>
> printf("argsArrayPtr->ip_addresses[0] = %s\n",argsArrayPtr->ip_addresses[0]);
> printf("argsArrayPtr->ip_addresses[1] = %s\n",argsArrayPtr->ip_addresses[1]);
>
> }
>
> this program prints:
>
> no_of_addresses 134514264
> argsArrayPtr->ip_addresses[0] = 10.0.0.0
> argsArrayPtr->ip_addresses[1] = 10.0.0.1
>
> where no_of_addresses should be 3;
> It is obviously a matter of performing malloc() to the ip_addresses[] array;
> but what should I exactly do it ? I do not know the sizes of the IP addresses :
> they can vary from 7 to 15 characters length .Moreover, I do not know the
> number of elements (ip addresses) in that array ; it is filled in run time
> from some file. (I do have an upper bound).
>
> regards,
> John


You do realize that standard IP address can be stored as 4 bytes
ie
byte[0] =10
byte[1] =0
byte[2] =0
byte[3] =0

people use 10.0.0.1 the computer uses 0x0A000000


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Allocating vector of strings seem to crash. Allocating array ofstrings seems to be ok . Rakesh Kumar C++ 5 12-21-2007 10:42 AM
Re: [Pyrex] Allocating an array.array of a specific length in pyrex Chris Lambacher Python 0 06-08-2005 06:56 PM
Allocating an array.array of a specific length in pyrex Chris Lambacher Python 0 06-08-2005 06:03 PM
allocating array in function modemer C++ 5 03-16-2005 02:12 PM
calling constructor when allocating an array Philipp C++ 21 09-17-2003 04:53 PM



Advertisments