c string

Discussion in 'C Programming' started by slurper, Nov 8, 2004.

  1. slurper

    slurper Guest

    if i do this

    char *mystring="mystring";

    later i reassign to mystring like this

    mystring="replacewithnewstring";

    i'm not a c expert, but i suppose i need to get rid of the dynamically
    assigned "mystring"? what should be done according to best practices ?
    free(mystring) ?

    tx
    slurper, Nov 8, 2004
    #1
    1. Advertising

  2. slurper

    Chris Dollin Guest

    slurper wrote:

    > if i do this
    >
    > char *mystring="mystring";
    >
    > later i reassign to mystring like this
    >
    > mystring="replacewithnewstring";
    >
    > i'm not a c expert, but i suppose i need to get rid of the dynamically
    > assigned "mystring"?


    There isn't one. Literal strings in C are statically allocated
    constants.

    > what should be done according to best practices ?


    Nothing.

    > free(mystring) ?


    That results in Undefined Behaviour. If you're very lucky,
    your program will crash.

    If you end up in a situation where you're losing the last reference
    to a string, and that string may or may not be dynamically allocated,
    and you don't know which, backtrack.

    --
    Chris "electric hedgehog" Dollin
    Chris Dollin, Nov 8, 2004
    #2
    1. Advertising

  3. slurper <> writes:

    > if i do this
    >
    > char *mystring="mystring";
    >
    > later i reassign to mystring like this
    >
    > mystring="replacewithnewstring";
    >
    > i'm not a c expert, but i suppose i need to get rid of the dynamically
    > assigned "mystring"? what should be done according to best practices ?
    > free(mystring) ?


    AFAIK this is done my the compiler, onlye if you make the following
    thing:

    char *mystring = malloc(9 * sizeof(char));
    my_string = "mystring";

    you'd have to free it, over a call to free, I think.

    Kind regrads,
    Nicolas

    --
    | Nicolas Pavlidis | Elvis Presly: |\ |__ |
    | Student of SE & KM | "Into the goto" | \|__| |
    | | ICQ #320057056 | |
    |-------------------University of Technology, Graz----------------|
    Nicolas Pavlidis, Nov 8, 2004
    #3
  4. Nicolas Pavlidis <> scribbled the following:
    > slurper <> writes:
    >> if i do this
    >>
    >> char *mystring="mystring";
    >>
    >> later i reassign to mystring like this
    >>
    >> mystring="replacewithnewstring";
    >>
    >> i'm not a c expert, but i suppose i need to get rid of the dynamically
    >> assigned "mystring"? what should be done according to best practices ?
    >> free(mystring) ?


    > AFAIK this is done my the compiler, onlye if you make the following
    > thing:


    > char *mystring = malloc(9 * sizeof(char));
    > my_string = "mystring";


    > you'd have to free it, over a call to free, I think.


    No, this is wrong. The assignment my_string = "mystring"; does *NOT*
    write the string "mystring" into the memory allocated by the malloc()
    call. Rather, it moves the pointer my_string to point at the string
    "mystring" (wherever it is stored), ignoring the memory allocated by
    malloc() completely.
    An attempt to call free(my_string) will cause undefined behaviour.
    It is exactly if you attempted to call free("mystring").
    Furthermore, all pointers to the memory allocated by malloc() have
    gone, so it has become what I call "ghost memory", i.e. memory that is
    allocated but impossible to use.
    You have to look up strcpy() instead.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "'So called' means: 'There is a long explanation for this, but I have no
    time to explain it here.'"
    - JIPsoft
    Joona I Palaste, Nov 8, 2004
    #4
  5. slurper

    slurper Guest

    Joona I Palaste wrote:

    > Nicolas Pavlidis <> scribbled the following:
    >> slurper <> writes:
    >>> if i do this
    >>>
    >>> char *mystring="mystring";
    >>>
    >>> later i reassign to mystring like this
    >>>
    >>> mystring="replacewithnewstring";
    >>>
    >>> i'm not a c expert, but i suppose i need to get rid of the dynamically
    >>> assigned "mystring"? what should be done according to best practices ?
    >>> free(mystring) ?

    >
    >> AFAIK this is done my the compiler, onlye if you make the following
    >> thing:

    >
    >> char *mystring = malloc(9 * sizeof(char));
    >> my_string = "mystring";

    >
    >> you'd have to free it, over a call to free, I think.

    >
    > No, this is wrong. The assignment my_string = "mystring"; does *NOT*
    > write the string "mystring" into the memory allocated by the malloc()
    > call. Rather, it moves the pointer my_string to point at the string
    > "mystring" (wherever it is stored), ignoring the memory allocated by
    > malloc() completely.
    > An attempt to call free(my_string) will cause undefined behaviour.
    > It is exactly if you attempted to call free("mystring").
    > Furthermore, all pointers to the memory allocated by malloc() have
    > gone, so it has become what I call "ghost memory", i.e. memory that is
    > allocated but impossible to use.
    > You have to look up strcpy() instead.


    tx for answers so far
    but i used string literals here, but suppose i use fgets in a loop to
    process all lines in a file. i store the lines in a variable (char*
    mystring). each line is assigned to the string variable. but what happens
    with the strings allocated to it earlear?
    for example:
    char* mystring;
    FILE *stream;
    if((stream = fopen ("filename", "r")) != (FILE *)0) {
    while((fgets(mystring, 1023, stream)) != (char *)0 ) {
    <process each line>
    }
    } else {
    <do fopen error handling>
    }
    but what happens with the strings i assign to mystring? will i end up with
    the whole file except the last line in memory, without references to it?
    i don't think C will delete it automatically, because if i say in the loop
    char* anotherstring=mystring, i'll end up with two references to the same
    string and the compiler can't know the string is still referenced by
    another variable.

    >
    slurper, Nov 8, 2004
    #5
  6. slurper <> scribbled the following:
    > Joona I Palaste wrote:
    >> No, this is wrong. The assignment my_string = "mystring"; does *NOT*
    >> write the string "mystring" into the memory allocated by the malloc()
    >> call. Rather, it moves the pointer my_string to point at the string
    >> "mystring" (wherever it is stored), ignoring the memory allocated by
    >> malloc() completely.
    >> An attempt to call free(my_string) will cause undefined behaviour.
    >> It is exactly if you attempted to call free("mystring").
    >> Furthermore, all pointers to the memory allocated by malloc() have
    >> gone, so it has become what I call "ghost memory", i.e. memory that is
    >> allocated but impossible to use.
    >> You have to look up strcpy() instead.


    > tx for answers so far
    > but i used string literals here, but suppose i use fgets in a loop to
    > process all lines in a file. i store the lines in a variable (char*
    > mystring). each line is assigned to the string variable. but what happens
    > with the strings allocated to it earlear?


    If you are indeed assigning the line to a string variable with the =
    operator, instead of strcpy() or a similar function, then the previous
    value is simply ignored. It is as if your code has:

    int a;
    a=1;
    a=2;

    and then you're asking what happens to 1 after the third line.
    Now, is it a bad thing that the previous values are ignored? It depends
    on how they were initially created. If they were string literals, such
    as:

    mystring = "Hello world!";

    then it's entirely OK, because string literals have program-wide
    storage, and the compiler will automatically claim them up when the
    program exits. However, if you used malloc() to allocate memory for
    them, for example:

    mystring = malloc(9); /* no need for sizeof(char) as it is always 1 */

    then you get what I called "ghost memory", i.e. a memory leak.

    > for example:
    > char* mystring;


    You should use malloc() to allocate some memory to store into mystring
    here.

    > FILE *stream;
    > if((stream = fopen ("filename", "r")) != (FILE *)0) {
    > while((fgets(mystring, 1023, stream)) != (char *)0 ) {


    This fgets() call does *NOT* assign a new value to mystring at all.
    The same value - i.e. the same memory location - is reused over and
    over again. Only the *contents* of that memory location change.
    Therefore it is entirely safe to overwrite the previous line with the
    next, without free()ing it. Actually, trying to free() it *would* be
    wrong, because then the next fgets() call would try to read data into
    unallocated memory.

    > <process each line>


    What does this <process each line> contain? Does it have any statements
    of the form

    mystring = /* ... */;

    ? If it doesn't, you're all OK, fine, kosher, hunky-dory. If it *does*,
    though, then you have to be careful not to end up with memory leaks.

    > }
    > } else {
    > <do fopen error handling>
    > }
    > but what happens with the strings i assign to mystring? will i end up with
    > the whole file except the last line in memory, without references to it?


    By the looks of it, I'd guess not. A definite not if my experience is of
    any use. It all depends on what you do in the <process each line> that
    you did not show. But if we ignore the <process each line>, then the
    above code is completely OK, as long as you remember to actually
    allocate some memory for mystring to point to. You should not end up
    with the whole file except the last line in memory if my intuition about
    your not shown code is of any good. Only the last line should remain in
    memory.

    > i don't think C will delete it automatically, because if i say in the loop
    > char* anotherstring=mystring, i'll end up with two references to the same
    > string and the compiler can't know the string is still referenced by
    > another variable.


    This won't matter. If you are indeed using the same value for mystring
    over and over again, as I suspect you are, then char *anotherstring =
    mystring will simply reuse the same value for anotherstring over and
    over again too. Both variables are *always* pointing to the *same*
    memory location. You can then later call free(mystring) or
    free(anotherstring) - BUT NOT BOTH - to free up the allocated memory.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "This is a personnel commuter."
    - Train driver in Scientific American
    Joona I Palaste, Nov 8, 2004
    #6
  7. slurper

    Chris Dollin Guest

    slurper wrote:

    > tx for answers so far
    > but i used string literals here, but suppose i use fgets in a loop to
    > process all lines in a file. i store the lines in a variable (char*
    > mystring). each line is assigned to the string variable. but what happens
    > with the strings allocated to it earlear?
    > for example:
    > char* mystring;
    > FILE *stream;
    > if((stream = fopen ("filename", "r")) != (FILE *)0) {
    > while((fgets(mystring, 1023, stream)) != (char *)0 ) {


    `mystring` doesn't point anywhere, so at this point you get Undefined
    Behaviour.

    In this example you could perfectly happily do

    char mystring[1023];

    and

    fgets( mystring, sizeof mystring, stream )

    > <process each line>
    > }
    > } else {
    > <do fopen error handling>
    > }
    > but what happens with the strings i assign to mystring? will i end up with
    > the whole file except the last line in memory, without references to it?


    No. You didn't allocate any memory, so it won't grow.

    If you don't need to keep all the strings you read, allocate `mystring`
    once - either as a local array, or with a call to `malloc` (and a matching
    `free` when you're done). If you *do* need to keep all the strings you read,
    then mallocate per line (and free them all when you're done).

    > i don't think C will delete it automatically, because if i say in the loop
    > char* anotherstring=mystring, i'll end up with two references to the same
    > string and the compiler can't know the string is still referenced by
    > another variable.


    Yes.

    --
    Chris "electric hedgehog" Dollin
    Chris Dollin, Nov 8, 2004
    #7
  8. slurper

    pete Guest

    slurper wrote:
    >
    > if i do this
    >
    > char *mystring="mystring";
    >
    > later i reassign to mystring like this
    >
    > mystring="replacewithnewstring";
    >
    > i'm not a c expert, but i suppose i need to get rid of the dynamically
    > assigned "mystring"? what should be done according to best practices ?
    > free(mystring) ?


    In the context of pointer assignment,
    the string literal is converted to a pointer to
    an array which resides in memory.
    The duration of that array, is until the end of the program.

    If you don't use a function like malloc or something similar,
    then you're not dealing with dynamic allocation.

    Identical string literals may refer to same or different objects.
    The exprsssion
    ("mystring" == "mystring")
    may be true in one part of a program
    and false in another part of the same program.

    --
    pete
    pete, Nov 8, 2004
    #8
  9. slurper

    bd Guest

    slurper wrote:

    > if i do this
    >
    > char *mystring="mystring";
    >
    > later i reassign to mystring like this
    >
    > mystring="replacewithnewstring";


    Yep.

    > i'm not a c expert, but i suppose i need to get rid of the dynamically
    > assigned "mystring"? what should be done according to best practices ?
    > free(mystring) ?


    No. "mystring" has static storage duration - it cannot be released. It is
    not dynamically allocated like memory from malloc() - next time the
    function is called (or the scope entered, or whatever) the pointer will be
    set to the same string, not a newly allocated one.

    >
    > tx
    bd, Nov 8, 2004
    #9
  10. slurper

    bd Guest

    Nicolas Pavlidis wrote:

    > slurper <> writes:
    >
    >> if i do this
    >>
    >> char *mystring="mystring";
    >>
    >> later i reassign to mystring like this
    >>
    >> mystring="replacewithnewstring";
    >>
    >> i'm not a c expert, but i suppose i need to get rid of the dynamically
    >> assigned "mystring"? what should be done according to best practices ?
    >> free(mystring) ?

    >
    > AFAIK this is done my the compiler, onlye if you make the following
    > thing:
    >
    > char *mystring = malloc(9 * sizeof(char));
    > my_string = "mystring";
    >
    > you'd have to free it, over a call to free, I think.


    First, mystring and my_string are different identifiers. Second, this is a
    memory leak - assigning the address of "mystring" will overwrite the
    address of the malloced memory, which can no longer be freed. You probably
    meant:
    char *mystring = malloc(9); /* sizeof(char) == 1 */
    strcpy(mystring, "mystring");
    /* do something with mystring */
    free(mystring);
    bd, Nov 8, 2004
    #10
  11. slurper

    Jim Guest

    On Mon, 08 Nov 2004 11:36:55 +0100, slurper <>
    wrote:

    > if((stream = fopen ("filename", "r")) != (FILE *)0) {
    > while((fgets(mystring, 1023, stream)) != (char *)0 ) {


    There's no need to do (FILE *)0 or (char *)0. Either 0 or NULL will
    do fine.

    Jim
    Jim, Nov 11, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mladen Adamovic
    Replies:
    0
    Views:
    733
    Mladen Adamovic
    Dec 4, 2003
  2. Mladen Adamovic
    Replies:
    3
    Views:
    14,591
    Mladen Adamovic
    Dec 5, 2003
  3. Matt
    Replies:
    3
    Views:
    498
    Tor Iver Wilhelmsen
    Sep 17, 2004
  4. Bruce Sam
    Replies:
    15
    Views:
    7,905
    John C. Bollinger
    Nov 19, 2004
  5. =?Utf-8?B?UmFqZXNoIHNvbmk=?=

    'System.String[]' from its string representation 'String[] Array'

    =?Utf-8?B?UmFqZXNoIHNvbmk=?=, May 4, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    1,801
    =?Utf-8?B?UmFqZXNoIHNvbmk=?=
    May 4, 2006
Loading...

Share This Page