Re: Reading a string of unknown size



santosh wrote:
Santosh wrote:
I have to read characters from stdin and save them in a string. The
problem is that I don't know how much characters will be read.
First include necessary headers: stdio.h, stdlib.h

int main()

Better yet, replace above with int main(void)

{
char *str = NULL, ch ;
int i = 0 ;
str = (char*) malloc (2*sizeof(char)) ;

Don't cast return value of malloc() in C.

This is not a bug. Note that without some sort of cast, there is no
type checking, which is the biggest risk when dealing with void *
pointers.

[...] It can hide the non-inclusion of it's prototype,

On *SOME* older generation compilers. No modern compiler fails to give
a warning about this regardless of the cast.

[...] (by way of failure to include stdlib.h), and, on
some implementations, can result in nasty crashes during runtime.

Since sizeof(char) is by definition 1, you can omit that and instead do
'2 * sizeof *str'. This has the advantage of becoming automatically
updated when you later on happen to change the type of *str.

If you want automatic type safety you should do this:

#define safeMallocStr(p,n,type) do { (p) = (type *) malloc
((n)*sizeof (type)); } while (0);

and you get type checking, and correct semantics. So if you change the
type of the variable you are using, your compiler will issue warnings
if you mismatch here. Any variation you do in which you omit the cast
outside of malloc will fail to catch this "change the definition of the
pointer" scenario.

i++ ;
str = (char*) realloc(str, (2*sizeof(char)) + i ) ;

[...]

Anyway, your allocation strategy is very inefficient. Your calling
realloc() once every iteration of the loop. This could result in
fragmentation of the C library's memory pool. Why not allocate in terms
of fixed sized

Because your memory pool will *still* fragment. It is also O(n^2)
rather than O(n) because of the implicit copying performed in
realloc().

[...] or dynamically growing blocks, say 128 bytes or so to
start with?

You have to do thing in exponential steps (doublings is the most
obvious was to do this) otherwise, weak malloc strategies will
inevitably be explosed. Its also going to be very slow for large
inputs (it really *IS* O(n^2)). So are you going to trade a buffer
overflow in just to be handed back a denial of service?

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

.



Relevant Pages

  • Re: about the array
    ... 3- If you cast to the wrong type by accident, ... are malloc and free. ... the compiler should issue a diagnostic - gcc ... unknown set of arguments, and return an int. ...
    (comp.lang.c)
  • Re: about the array
    ... I guess the bottom line is - if the cast isn't necessary, why do it, esp. ... the compiler should issue a diagnostic - gcc gives: ... it], and screw up, e.g., without the declaration, the compiler *should* ... maybe the int taken by the ...
    (comp.lang.c)
  • Re: free() multiple allocation error in C
    ... Why shouldnt one cast malloc? ... If you don't include the compiler does not see a prototype ... for `malloc` and is forced to assume it returns an `int`. ... pointer returned by `malloc` as an `int` and then convert that `int` ...
    (comp.lang.c)
  • Re: va_arg and short
    ... >> short is promoted to int. ... >> remove it) and no compiler is going to warn you about it. ... The cast, if enforced, ensures that the value ... > Is the compiler required to enforce the cast, such that the value can never ...
    (comp.lang.c)
  • Re: Small C "Puzzle"
    ... > compiler under Linux). ... the types of the predefined integer types are: ... > int 32 bits ... Why not cast? ...
    (comp.lang.c)