Thread: malloc 1d string array

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    55

    malloc 1d string array

    Hi all,
    I'm' writing a program in which I can't get round to see what I am doing wrong in a small part of it that deals with:
    -dynamically allocating a 1d string array (or 2d char array..)
    -reading a file and storing each line in a string (as previously allocated)

    I would be grateful if you could direct me in debugging my program. Here's the relevant pieces code:

    Code:
    #include<stdio.h>       /* for input and output */
    #include<stdlib.h>      /* for memory management */
    #include<string.h>      /* for memset */
    
    int main(void) {
    
            unsigned int nrows=0;                   /* number of data rows in the file */
            unsigned int comment=0;                 /* number of comment lines in file */
            unsigned int i=0;                           /* counters */
            const unsigned int linelen=700;         /* length of buffer line */
            FILE *fp=NULL;                          /* pointer to file to read data */
            char oldname[30];                       /* name of file to read */
            char **buff=NULL;                       /* buffer line */
            char templine[700];                     /* temporary line for initial reading of the file */
    
            /* open a file to read */
            printf("Enter the name of the file you want to read data from: ");
            scanf("&#37;s", oldname);
            if (!(fp=fopen(oldname,"r"))) {
                    perror(oldname);
                    exit(1);
            }
    
            /* count the number of comment lines, and data lines */
            while (fgets(templine,sizeof(templine),fp)!=NULL) {
                    if (templine[0]=='#') {
                            comment++;
                    } else {
                            nrows++;
                    }
            }
            printf("\nThere are %u comments and %u rows", comment, nrows);
    
            /* allocate string array to write all the lines from the file */
            buff=malloc((comment+nrows)*sizeof(*buff));
            if (buff==NULL) {
                    printf("\nCould not allocate  pointer array");
            }
            for (i=0; i<(comment+nrows); i++) {
                    buff[i]=malloc(linelen*sizeof(*buff[i]));
                    if (buff[i]==NULL) {
                            printf("\nCould not allocate array %u", i);
                    }
            }
    
            /* read all lines into buffer, and print to screen */
            rewind(fp);
            for (i=0; i<(comment+nrows); i++) {
                    fgets(buff[i],sizeof(buff[i]),fp);
                    printf("\n%s", buff[i]);
            }
    
            /* clean up memory */
            fclose(fp);
            for (i=0; i<(comment+nrows); i++) {
                    free(buff[i]);
            }
            free(buff);
    
            return 0;
    }
    EDIT: When I run the code above, I'm getting the result of every three characters to be written to each of the 1d string arrays. This looks like maybe I'm not allocating enough space for the length of my string, even though I want to set it as 700 via the "linelen" variable.

    Also, I'm wondering why for array indexing, people generally use "int" and not "unsigned int"? It seems for me that "unsigned int" is more appropriate because of the +ve range being bigger, and because of no need for negative numbers when indexing an array.

    Thanks!
    Spiros
    Last edited by s_siouris; 07-07-2008 at 08:40 AM. Reason: Added more info on what happens when I run the above program

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    1) Well, for the array indexing just to avoid the "unsigned" thing. Though there are a lot of people that use the unsigned thing. Not a huge difference. Especially in C99, writing
    Code:
    if (unsigned int i=0; ....)
    looks much bigger than the simple int i=0 :P

    If you pas iterator i to a function that want int and not unsigned int then you will avoid a compiler's warning and maybe an error.
    If for example you want to do something with the iterator like "sum = i*b" then it might be slightly faster to have i the same type as b.

    Generally, unsigned and signed are similar but not the same! It might be easier avoiding a bug if you had it signed rather unsigned.

    Not supporting anything, just note that in some cases there might be a difference and one more correct than the other.

    2) I ll check your code and see in a while
    EDIT: OK found the fault
    Code:
    change this (line 49)
    fgets(buff[i],sizeof(buff[i]),fp);
    with this:
    fgets(buff[i],linelen*sizeof(*buff[i]),fp);
    Also, fgets "reads" and stores the '\n' character. So change this
    Code:
    this (line 50):
    printf("\n&#37;s", buff[i]);
    with this:
    printf("%s", buff[i]);
    and you are done
    Last edited by C_ntua; 07-07-2008 at 09:10 AM.

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Code:
    buff[i]=malloc(linelen*sizeof(*buff[i]));
    Code:
    fgets(buff[i],sizeof(buff[i]),fp);
    sizeof(*buff[i]) will be a size of a char, and sizeof(buff[i]) will be the size of a char *.

    sizeof() doesn't do anything for you in terms of the length of a dynamically sized buffer.

  4. #4
    Registered User
    Join Date
    Nov 2004
    Posts
    55
    that's brilliant guys, i've understood what was wrong. Thanks a lot for the explanations of the outputs of sizeof(buff[i]), and sizeof(*buff[i]).

    many thanks
    Spiros

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String issues
    By The_professor in forum C++ Programming
    Replies: 7
    Last Post: 06-12-2007, 09:11 AM
  2. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM
  3. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  4. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM