Re: unusual behaviour of program under linux....

From: David Schwartz (davids_at_webmaster.com)
Date: 06/19/03


Date: Thu, 19 Jun 2003 14:50:06 -0700


"seemanta dutta" <seemanta_18@yahoo.com> wrote in message
news:fd383985.0306191335.2a958d15@posting.google.com...

> greetings linux gurus...

    None of your questions have anything to do with Linux.

> 1. i feel ashamed, but what exactly is an uninitialised pointer?
> is
> int *localVar;
> *localVar = 3 ;
> an uninitialised pointer?

    Yes.

> or is this is an *initialised* pointer?
> int *localVar;
> localVar = malloc(sizeof int);

    That is an initialized pointer.

> 2. in some of my programs i have to read from a file and write to a
> different file using fgets and fprintf...
>
> what i want to ask is that when i declare my buffer for fgets as
> char *buff;
>
> my program compiles alright but while running it gives a seg fault..i
> can understand this is because of a buffer overflow,

    It's not because of a buffer overflow, it's because you've allocated a
pointer to a bunch of characters but never made it point anywhere.

> but if i use a
> declaration like this for my buffer
> char buff[80];
> my seg fault disappears...

    Right, because that allocates space for 80 characters.

> but here i am implicitly assuming my data will never be larger that 80
> bytes...if my data exceeds 80 bytes there occurs another seg fault and
> my program exits...

    Right.

> is it a good practice to use limited size buffers for file i/o?

    Yes, but you should also limit the I/O so it can't overflow the buffers.

> what i want to know is that is there any way to write code for file
> i/o ,or any i/o for that matter which shall be independent of the
> amount
> of data entered by the user or of that amount of characters present
> in a line of the file read by a call to fgets.

    Since 'fgets' allows you to specify the maximum number of characters it
will return, there should be no problem.

> it is there that i am facing the problem with limited size buffers for
> performing file i/o with 80 byte-sixed buffers...

    So crank it up to 1,024 byte buffers and limit your I/O to that.

> 3. in some of my programs like this..
>
> int main()
> {
>
> char deststr[20],srcstr1[20]="foo",srcstr2[20]="bar";
> deststr=strcat(srcstr1,srcstr2); // insertion of 4 given
> lines made here in place of this line...
> puts(deststr);
> return 0;
> }
>
> but the above program compiles with the following error: t.c: In
> function `main':
> t.c:8: incompatible types in assignment

    Right "foo" is a pointer to characters but char[20] is an array of
characters. You can't equate them that way. Maybe you want:

char srcstr1[20];
strcpy(srcstr1, "foo");

> if the man page says that strcat returns a 'char *' and since the name
> of a char array implies a pointer to a char, why is this giving an
> error?

    Because you're trying to move the array. 'deststr' is a pointer to the
first character of an array. You are attempting to change that pointer to
point to the return value of 'strcat', but the array can't move, it's memory
address is constant.

    The 'strcat' function appends one string onto another. The return value
is the address of the finished string. You are trying to say "set the
address of my array equal to the address of the string I just made". Try:

strcpy(deststr, strcat(...));

    This says "copy into the address indicated by 'deststr' a string
starting at the address returned by 'strcat'".

> if i replace the declaration of deststr with char *deststr;
> i no longer get any error, but on running i get a seg
> fault...

    I'm not sure exactly what, but that just makes 'destr' point to
'strcstr1'.

>obviously due to a buffer overflow and if i use desstr[20] i
> get the above
> error.
> what to do? it is a catch22 kind of situation for me... i cannot use
> *deststr because of buffer overflows,neither can i use deststr[20] for
> it does allow me to use strcat as i want to...
> and gives an error

    Copy the string into the array.

> if i insert these lines in place of the second line above, i can use
> deststr[20] instead...but at the expense of a few more lines of
> code...
> and a limited buffer size of deststr[20]...
>
> char temp[30];
>
> strcpy(temp,srcstr1);
> strcat(temp,srcstr2);
> strcpy(deststr,temp);
>
> but is it ok to involve another variable like this and use an awkward
> strcpy and a limited buffer size?

    This is a very different thing because this doesn't modify 'strcstr1'.
If you didn't want to modify 'strcstr1', why not do the operation in
'destrstr', like this:

char deststr[MAX_LENGTH];
strcpy(deststr, srcstr1);
strcat(deststr, srcstr2);

> please advise where i am making a mistake...

    You're just not keeping in mind what the statements you're using
actually *mean*. :)

> 4. please consider the following code:
>
> #include<stdio.h>
> #include<stdlib.h>
> #include<string.h>
>
> char * foo(void);
>
> int main()
> {
>
> char *ptr ;
> ptr = foo();
> puts(ptr);
> return 0;
>
> }
>
>
> char * foo()
> {
> char *retval; //using retval[10] causes warning...but using
> *retval doesnot..
> strcpy(retval,"hello"); //why is strcpy allowed here?

    Ack! This copies the string "hello" to noplace in particular!

> should'nt a seg fault occur here?

    The results of doing this are undefined.

> return retval; //using strcat also does not cause a
> seg fault...
>
> // question: is there a memory leak in this code if i add the line
> 'retval=malloc(7);' after retval declaration?

    Yes, callers ot 'foo' will have to know to call 'free' on the pointer
returned.

> }

> in the first line in foo(),if i replace *retval with retval[20] or
> something like it, i get a warning saying
> warning: function returns address of local variable

    Right, because as soon as the function returns, 'retval' ceases to
exist, so how can you return its address?

> is that an unacceptable practice to return address of an auto
> variable?

    Yes. Since the variable ceases to exist, its previous address is
meaningless.

> and in one program i was using such a variable by malloc'ig some
> bytes...
> char *retval;
> retval=malloc(5);
> strcpy(retval,"hello");
> ...
> return retval;

    First, that needs to be malloc(6). (Do you understand what a C string
is?)

> using malloc call in place of retval[20] also removes the above
> warning.

    Right.

> but this has put me into worries since i have read in books that
> malloc() calls that do not have any corresponding free() calls cause
> memory leaks...
> so in this case i ought to call free()

    Right.

> but if i call free before i call return my pointer that would return a
> garbage pointer, is n't it?

    Correct.

> but on the other hand i must free() my memory also...as well return my
> pointer to the calling function...
> how to write code that would prevent memory leaks as well as won't
> give any warnings as shown above...

    The code that calls the function knows when it no longer needs the
memory, so it can call 'free' at the appropriate time. A static buffer might
also work.

    DS



Relevant Pages

  • [net-next PATCH 4/5] igb: Add support for enabling VFs to PF driver.
    ... pointer to the hardware struct ... under the terms and conditions of the GNU General Public License, ... * @msg: The message buffer ... * returns SUCCESS if it successfully copied message into the buffer ...
    (Linux-Kernel)
  • Re: Reading long lines from a file
    ... start with a statically allocated buffer and a pointer of equal ... you can't reallocate a statically allocated buffer! ... Once we get those impossibilities out of the way, we can dispense with the unnecessary fgets call - your input is already buffered, so why buffer it again through fgets? ...
    (comp.lang.c)
  • Re: Simple C containers, std::vector analog
    ... the computing power of thiry ... Thirty years ago it was 1975 and computers ran in Kilohertz ... and some implementations do choke on realloc'ing a null pointer. ... template f void f(voidpT buffer){ ...
    (comp.lang.c)
  • Re: some unanswered questions on C
    ... A pointer variable that's never been given a value. ... you don't know what memory you're modifying. ... >what i want to ask is that when i declare my buffer for fgets as ... "char *buffer" creates a pointer, ...
    (comp.unix.programmer)
  • [patch] x86, ptrace: PEBS support
    ... BTS and PEBS recording. ... * - buffer overflow handling ... (interrupt occurs when write pointer passes interrupt pointer) ... * guarding context and buffer memory allocation. ...
    (Linux-Kernel)