Novice question about malloc and pointers 
Author Message
 Novice question about malloc and pointers

I am trying to get an array of strings, therefore I am using the
following declaration:  char *str[MAX] where MAX is an arbitrary
constant.  My question is how do I allocate the memory for each
character position? Do all the characters strings for each element
in the array need to be allocated contiguously?  The problem involves
reading in lines of input.  Each line would be stored as a string and
the number of lines make up the number of elements in the array.
Any information would be greatly appreciated.  Thank you.




Mon, 04 Oct 1993 00:14:59 GMT  
 Novice question about malloc and pointers

Quote:
>I am trying to get an array of strings, therefore I am using the
>following declaration:  char *str[MAX] where MAX is an arbitrary
>constant.  My question is how do I allocate the memory for each
>character position? Do all the characters strings for each element
>in the array need to be allocated contiguously?  The problem involves
>reading in lines of input.  Each line would be stored as a string and
>the number of lines make up the number of elements in the array.
>Any information would be greatly appreciated.  Thank you.

        Here's how I did something similar:  use a temporary variable
such as char buf[200] for getting each line of input, then do a
str[i] = (char  *) malloc(strlen(buf) +1)
to copy each line into str.

---
John Gordon




Mon, 04 Oct 1993 04:32:53 GMT  
 Novice question about malloc and pointers

Quote:
>I am trying to get an array of strings, therefore I am using the
>following declaration:  char *str[MAX] where MAX is an arbitrary
>constant.  My question is how do I allocate the memory for each
>character position?

I assume by "character position" you really mean each pointer in the
array; each one can be malloc'ed separately, one string at a time.

Quote:
>Do all the characters strings for each element
>in the array need to be allocated contiguously?

Unless your application wants to run blindly off the end of one string and
onto the next (sounds like a bad idea to me), each string can be discontigous
with the others.  Each string represents a contiguous block of memory, note,
so one string won't be represented by several pieces.

Quote:
>The problem involves reading in lines of input.
>Each line would be stored as a string and
>the number of lines make up the number of elements in the array.

Here is where the Art of programming comes in.  The most obvious implementation
(which arbitrarily limits each line to 512 bytes plus newline) is:

        #include <stdio.h>
        ...
        #define MAX 666
        char *str[MAX];
        ...
        snuffle_file(f)
        FILE *f;
        {
                char buf[514], *p;
                int i;
                /* Read in lines from the file f */
                for (i = 0; i < MAX; i++) {
                        /* Read in a line */
                        if (fgets(buf, 514, f) == NULL) break;
                        /* Treasure the line in a copy */
                        if ((str[i] = malloc(strlen(buf))) == NULL) {
                                fprintf(stderr,"Go buy more memory.\n");
                                return;
                        }
                        strcpy(str[i], buf);
                        /* Note that if you have strdup() the above 5 lines
                         * become:
                         * if ((str[i] = strdup(buf)) == NULL) {
                         *      <gripe>
                         * }
                         */
                }
        }

This isn't necessarily the best one can do, though; arbitrary line length
limits are annoying, so the first obvious improvement is to replace the
fgets-into-a-buffer strategy with something like (in pseudo-C)

        newstring = malloc(some pittance likely to hold most lines, like 32)
        while not-yet-eof and haven't-seen-a-newline
                fgets into a buffer
                if there's not enough room in newstring to add the buffer to
                the end,
                        newstring = realloc(newstring, current size + some)
                        /* remember that memory can run out */
                add buffer contents to end of newstring
        newstring = realloc(newstring, actual size) /*free a few bytes at end*/

I believe that 4.4BSD will have a "readline()" function that does roughly
that, or you can figure out how to roll your own, or dig up any one of the
innumerable versions that have been lodged in netnews postings over the past
decade.

The next annoying limit that should die is "MAX":  a similar strategy of
realloc-if-out-of-room can be used to remove the arbitrary limit on the
number of lines.

Something else to ponder is:  if you *know* that the file size is relatively
small in comparison to the amount of memory you have, and if you *know* that
your OS does reasonable things for large reads from files, it *may* be worth
mallocing a contiguous buffer which is large enough to hold the file, slurp it
all in with one single read, and then pick it apart into lines.  Note that
this strategy may perform poorly on someone else's machine for perfectly good
reasons, and worse, may misfire badly the first time some clown gives your
program a 16Mb text file when you "knew" the limit would be 16Kb.  Balancing
the tradeoffs well is an art.



Mon, 04 Oct 1993 05:31:06 GMT  
 Novice question about malloc and pointers

Quote:

>>I am trying to get an array of strings...
>>...how do I allocate the memory for each [string]?
>The most obvious implementation... is:
[most code deleted]
>                    /* Treasure the line in a copy */
>                    if ((str[i] = malloc(strlen(buf))) == NULL) {

Make that malloc(strlen(buf) + 1).  (Side note: never tangle your
fingers and type malloc(strlen(buf + 1)), either.)

Quote:

>...do a
>str[i] = (char  *) malloc(strlen(buf) +1)
>to copy each line into str.

make that "do [a malloc], *then* copy each line into str."

                                            Steve Summit



Tue, 05 Oct 1993 08:17:39 GMT  
 Novice question about malloc and pointers

Quote:


>>                        /* Treasure the line in a copy */
>>                        if ((str[i] = malloc(strlen(buf))) == NULL) {
>Make that malloc(strlen(buf) + 1).  (Side note: never tangle your
>fingers and type malloc(strlen(buf + 1)), either.)

Oops.

Consider that another reason to use strdup() if you've got it.

Assuming the library writer didn't{*filter*}up, too.       :-)



Sat, 09 Oct 1993 00:48:37 GMT  
 Novice question about malloc and pointers

Quote:
>constant.  My question is how do I allocate the memory for each

                                    ^^^^^^^^
            Malloc , my dear Russell. Malloc !
Quote:
>character position? Do all the characters strings for each element
>in the array need to be allocated contiguously?  The problem involves

                                   ^^^^^^^^^^^^
            Did't you know that memory is linear ! ( NO )

Quote:
>reading in lines of input.  Each line would be stored as a string and
>the number of lines make up the number of elements in the array.
>Any information would be greatly appreciated.  Thank you.

            This proves without doubt 'Ignorance is NOT bliss'.

         Solution :
         #include <string.h>
         #include <malloc.h>
         #include <stdio.h>

         #define MAX 20
         #define MAX_SZ 512

         char *str[MAX];

         Read_Input()
         {
            int i;
            char buff[MAX_SZ];

            for ( i = 0 ; i < MAX ; i++ )
               str[i] = malloc(strlen(gets(buff)+1)),
               strcpy(str[i],buff);
         }

         C S Palkar
         --

Quote:





Wed, 13 Oct 1993 02:56:05 GMT  
 Novice question about malloc and pointers

Quote:

>        for ( i = 0 ; i < MAX ; i++ )
>           str[i] = malloc(strlen(gets(buff)+1)),
>           strcpy(str[i],buff);

My, my, my -- live on the edge, don't we?
Using malloc without checking the return value is risky, at best...

                                                - Greg

--



Sat, 16 Oct 1993 06:43:47 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Novice question on vectors of pointers

2. arrays of pointers - NOVICE QUESTION!( Be forwarned ! )

3. novice pointers question

4. NOVICE question - passing pointers help?

5. Novice questions bout string functions and pointers?

6. Some interesting novice questions from a novice guy

7. Pointer, malloc question

8. SIMPLE malloc & pointer question

9. Novice Q: Understanding malloc()......

10. C question : redefining a new malloc() calling standard malloc()

11. to malloc() or not to malloc(), that is the question

12. Novice: Passing a function pointer to a function

 

 
Powered by phpBB® Forum Software