Thread: String allocation

  1. #1
    fw9189
    Guest

    Cool String allocation

    Dear all, is there a simple way of reading from stdin to a char * without having to allocate memory before reading. I.e. dynamically allocating as much mem as we need?

    Thanks,

    Fred

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    No.
    You must read in using fixed length buffers (which may then be partially filled), then you must allocate as required.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Unregistered
    Guest
    > No.
    > You must read in using fixed length buffers (which may then be
    > partially filled), then you must allocate as required.

    This is wrong. Actually, it is not wrong if you count a single character as a "fixed length buffer". You can do this in DOS by using the kbdhit() function. It goes something like this:
    Code:
    char buffer = '\0'; // ;)
    char *buf = NULL;
    
    puts("Type stuff now. Press CTRL-Z to stop.");
    while( !kbdhit( ) )
    {
       buffer = getc( );
       if ( !buf )
       {
          buf = malloc( sizeof( char ) * 2 );
          buf[1]='\0';
       }
       buf = realloc( sizeof( buf ) + 1 );
       sprintf( buf, "%c%s" buffer, buf );
    }
    Something like that. I don't recall exactly, but you can do it.

    Quzah.

  4. #4
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    >> buf = realloc( sizeof( buf ) + 1 );
    Are you sure your program compiled ?

    void* realloc(void* p, size_t size);
    Returns pointer to newly-allocated space for an object of size size, initialised, to minimum of old and new sizes, to existing contents of p (if non-null), or NULL on error. On success, old object deallocated, otherwise unchanged.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > This is wrong.
    Mmm - how is it wrong, when you then try and provide an example to back up my claim?

    Your example calls malloc (read my reply "then you must allocate as required"), and uses a fixed sized buffer (a single char) but you seem to have made a number of serious errors.

    And who said keyboard was my input and DOS was my operating system?

    > buf = malloc( sizeof( char ) * 2 );
    Should be sizeof(char) + 1;

    And your use of realloc is broken
    > buf = realloc( sizeof( buf ) + 1 );
    1. buf is a pointer, so sizeof doesn't tell you the right thing
    2. if realloc returns NULL, you've lost your only pointer to the allocated memory.

    > sprintf( buf, "%c%s" buffer, buf );
    Mmm, does this fill up the whole of memory with the first key press?
    I mean, the 2nd parameter is buf, and you treat it as a string, but the string keeps growing because it's the same buff you're writing to.

    It was my impression that fw9189 wanted a function like fgets which would allocate space as required. As I stated before, there is no standard function to do this.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Unregistered
    Guest
    >> This is wrong.
    >Mmm - how is it wrong, when you then try and provide an >example to back up my claim?

    Well, as I said, if you count a single character as a fixed length buffer, then it isn't. And actually, _any_ input is stored in a keyboard buffer first, there is no way around it being buffered.

    > And who said keyboard was my input and DOS was my
    > operating system?

    I didn't say yours was DOS. I said there is a way to do it in DOS. There is probably a way to do it in *nix if you use the ncurses lib and link with that.

    The original

    >> buf = malloc( sizeof( char ) * 2 );
    >Should be sizeof(char) + 1;

    This is the exact same thing. Actually, it isn't. If you have a char that is more than one byte, then your example is wrong. Since it is theoreticly(sp) possible for char to be defined as something larger than 1, mine is correct. In reality, they're both correct. Mine is "safer". I actually had it as +1 first, but changed it.

    As the previous poster wrote "Are you sure this compiles?", no I'm not. It's pseudocode. I rarely compile examples I type up. It is a point of refrence.

    > And your use of realloc is broken
    >> buf = realloc( sizeof( buf ) + 1 );
    > 1. buf is a pointer, so sizeof doesn't tell you the right thing
    > 2. if realloc returns NULL, you've lost your only pointer to the
    > allocated memory.

    Yeah, it should have been strlen(). You'd be hard pressed to make realloc fail here (assuming I used strlen()). It's possible, but you're have to be really bored to do so. In reality, you'd likely fill your keyboard buffer before ever running out of memory from a realloc failure.

    >> sprintf( buf, "%c%s" buffer, buf );
    > Mmm, does this fill up the whole of memory with the first key ?
    > press?
    > I mean, the 2nd parameter is buf, and you treat it as a string,
    > but the string keeps growing because it's the same buff you're
    > writing to.

    Yeah. You're right here. I have those two backwards. You can only use this to append to the string. (I was thinking the other way around.

    > It was my impression that fw9189 wanted a function like fgets
    > which would allocate space as required. As I stated before,
    > there is no standard function to do this.

    Actually no one said anything about standards, which is why I replied. You can basicly mimic the fgets() behaviour, but it's ugly and has to be supported by your OS/Libs you're using. (Which is why I mentioned you can do it in DOS.

    And yeah, I left a parameter off of my realloc call. It should go something like:
    Code:
    char *mykbdreader( )
    {
       char *buf=NULL, *tbuf=NULL, c;
    
       while( !kbdhit() )
       {
          c = getc();
          if( !buf )
          {
             buf = malloc( sizeof( char ) * 2 ); //or +1
             //either way is correct.
             //void *malloc(size_t nbytes);
             buf[1]='\0';
          }
          tbuf = malloc( strlen( buf ) + 1 );
          tbuf[0] = c;
          strcat( tbuf, buf );
          free( buf );
          buf = tbuf;
          tbuf = NULL;
       }
       return buf;
    }
    Again, this likely will not compile unless you have a DOS compiler. I don't, so I haven't tried it. I know you _can_ do what the original poster wants, but it is OS / Implementation dependent. It's not the best way to do it, but that, in theory, should work. I wasted a byte there with tbuf, but that's forgiveable and I don't really feel like rewriting this.

    Quzah.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ ini file reader problems
    By guitarist809 in forum C++ Programming
    Replies: 7
    Last Post: 09-04-2008, 06:02 AM
  2. Replies: 4
    Last Post: 03-03-2006, 02:11 AM
  3. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  4. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  5. creating class, and linking files
    By JCK in forum C++ Programming
    Replies: 12
    Last Post: 12-08-2002, 02:45 PM