Pointers and Arrays in C

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Terence

    Pointers and Arrays in C

    I usually program in Java, so I am a bit confused about usint pointers in C.
    I would really appreciate if someone can help me.

    Case 1:
    ======

    // Is this function no good? Since str is a variable created on stack,
    // I am assuming it will be deallocated immedately after the function returns,
    // right??
    char * generateString( )
    {
    char str[100] = "abc";
    return str;
    }

    Case 2:
    =====

    // str is a pointer pointing to a literal
    // Can I use str just like other char arrays?
    // How are memory allocated for literals and when are they deallocated??
    void main()
    {
    char * str;
    str = "abc";
    }

    Case 3:
    =====

    // Similar to case 2 except the literal is returned from a function
    // Again, can I use str for anything? When is it deleted from memory??
    void main()
    {
    char * str;
    str = generateString( );
    }

    char * generateString( )
    {
    return "abc";
    }

    Case 4:
    =====

    // assigning dynamically allocated array to pointer
    void main()
    {
    char * str;
    str = generateString( );
    ...
    delete str; // I have to delete str at the end, Right?
    }

    char * generateString( )
    {
    char * charArray = new char[20];
    strcpy(charArra y, "abc");
    return charArray;
    }

    Case 5:
    =====

    // str points to a char array created in a C library function
    // How was this char array allocated? When will it be deallocated?
    // Do I have to delete it explicitly??
    void main()
    {
    char line[20] = "abc#def";
    char * str;

    str = strtok(line, "#");

    delete str; // is this necessary?
    // can I modify the content of the array??
    }


  • Artie Gold

    #2
    Re: Pointers and Arrays in C

    Terence wrote:[color=blue]
    > I usually program in Java, so I am a bit confused about usint pointers in C.
    > I would really appreciate if someone can help me.
    >
    > Case 1:
    > ======
    >
    > // Is this function no good? Since str is a variable created on stack,
    > // I am assuming it will be deallocated immedately after the function returns,
    > // right??[/color]

    You are fundamentally correct (it may or not actually be
    *deallocated* but it no longer logically exists once the block in
    which it is declared is exited).
    [color=blue]
    > char * generateString( )
    > {
    > char str[100] = "abc";
    > return str;
    > }
    >
    > Case 2:
    > =====
    >
    > // str is a pointer pointing to a literal
    > // Can I use str just like other char arrays?
    > // How are memory allocated for literals and when are they deallocated??
    > void main()[/color]

    Say it with me:
    main() returns int main() returns int main() returns int
    [color=blue]
    > {
    > char * str;
    > str = "abc";
    > }
    >[/color]

    A literal exists for the life of the program. The mechanism is
    irrelevant (and an issue for the implementation) . It may not be mutable.
    [color=blue]
    > Case 3:
    > =====
    >
    > // Similar to case 2 except the literal is returned from a function
    > // Again, can I use str for anything? When is it deleted from memory??
    > void main()
    > {
    > char * str;
    > str = generateString( );[/color]

    Yes -- but don't try to change it.
    [color=blue]
    > }
    >
    > char * generateString( )
    > {
    > return "abc";
    > }
    >
    > Case 4:
    > =====
    >
    > // assigning dynamically allocated array to pointer
    > void main()[/color]

    Say it with me:
    main() returns int main() returns int main() ...
    [color=blue]
    > {
    > char * str;
    > str = generateString( );
    > ...
    > delete str; // I have to delete str at the end, Right?
    > }
    >
    > char * generateString( )
    > {
    > char * charArray = new char[20];
    > strcpy(charArra y, "abc");
    > return charArray;
    > }[/color]

    Correct.
    [color=blue]
    >
    > Case 5:
    > =====
    >
    > // str points to a char array created in a C library function
    > // How was this char array allocated? When will it be deallocated?
    > // Do I have to delete it explicitly??
    > void main()
    > {
    > char line[20] = "abc#def";
    > char * str;
    >
    > str = strtok(line, "#");
    >
    > delete str; // is this necessary?[/color]

    Not only unnecessary -- but doing so would invoke undefined
    behavior, likely resulting in a crash (but only if you're lucky; the
    other possibilities are considerably more frightening).
    [color=blue]
    > // can I modify the content of the array??[/color]

    Yes you can. Be aware, however, that strtok alters what its first
    argument points to -- so what `str' points to might surprise you.
    Reaed whatever documentation is available at least twice before
    using strtok().
    [color=blue]
    > }
    >
    >[/color]

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    Oh, for the good old days of regular old SPAM.

    Comment

    • Dave Vandervies

      #3
      Re: Pointers and Arrays in C

      In article <N6hob.117126$3 f.4704@twister0 1.bloor.is.net. cable.rogers.co m>,
      Terence <findty@hotmail .com> wrote:[color=blue]
      >I usually program in Java, so I am a bit confused about usint pointers in C.
      >I would really appreciate if someone can help me.[/color]

      If you haven't already, go read the FAQ at


      This will probably answer a lot of your questions faster than waiting for
      a reply on the newsgroup, though a quick look to refresh my memory didn't
      find anything about a few of these (the ones about string literals).


      [color=blue]
      >Case 1:
      >======
      >
      >// Is this function no good? Since str is a variable created on stack,
      >// I am assuming it will be deallocated immedately after the function returns,
      >// right??[/color]

      That's correct. str goes away when generateString returns, and the
      pointer to it that you're returning becomes invalid.
      [color=blue]
      >char * generateString( )
      >{
      > char str[100] = "abc";
      > return str;
      >}[/color]

      [color=blue]
      >Case 2:
      >=====
      >
      >// str is a pointer pointing to a literal
      >// Can I use str just like other char arrays?[/color]

      Almost; you can't modify it, but otherwise, yes. (So you can treat it
      exactly like you would treat any other array of const char.)
      [color=blue]
      >// How are memory allocated for literals and when are they deallocated??[/color]

      They are allocated before the program starts and deallocated after it
      ends, so any pointer you have that points at a string literal will be
      valid anywhere you use it.
      [color=blue]
      >void main()[/color]

      main always returns int in both C and C++.
      (Hmm, you said you're coming from Java, didn't you? Excuse me for
      a minute while I go poke my sigmonster with a pointy stick... There,
      that's better.)
      [color=blue]
      >{
      > char * str;
      > str = "abc";
      >}[/color]


      [color=blue]
      >Case 3:
      >=====
      >
      >// Similar to case 2 except the literal is returned from a function
      >// Again, can I use str for anything? When is it deleted from memory??[/color]

      Yes. What you're returning is a pointer to the first element in the
      array represented by the string literal; unlike the array on the stack
      in case 1, this will still be there when generateString returns.
      [color=blue]
      >void main()
      >{
      > char * str;
      > str = generateString( );
      >}
      >
      >char * generateString( )
      >{
      > return "abc";
      >}[/color]

      [color=blue]
      >Case 4:
      >=====
      >
      >// assigning dynamically allocated array to pointer[/color]

      This is almost correct.
      Aside from the void main that I've noted elsewhere, you also have a
      mismatched new/delete; memory allocated with "new type[size]" needs to
      be deallocated with delete[], not plain delete.

      But yes, you do have to deallocate the memory you allocated in
      generateString when you're done with it. Every new needs a matching
      delete.

      [color=blue]
      >void main()
      >{
      > char * str;
      > str = generateString( );
      > ...
      > delete str; // I have to delete str at the end, Right?
      >}
      >
      >char * generateString( )
      >{
      > char * charArray = new char[20];
      > strcpy(charArra y, "abc");
      > return charArray;
      >}[/color]

      [color=blue]
      >Case 5:
      >=====
      >
      >// str points to a char array created in a C library function
      >// How was this char array allocated? When will it be deallocated?
      >// Do I have to delete it explicitly??[/color]

      Using strtok for this is a bad example, because it works on the string
      you give it and doesn't create a copy for you, so in your example you
      don't need to deallocate str (since it points into memory that will be
      deallocated for you when the function returns) and you can modify it
      (as long as you don't step outside the bounds of your 20-element array).
      In fact, I don't know of any C library functions (besides the obvious
      malloc and friends) that allocate memory for you, so I'm not sure your
      question as asked makes sense.

      If your question referred to strdup (a unixism that copies a string
      into memory obtained from malloc), the answer would be that you need to
      release that memory by passing the pointer you got from strdup to free()
      when you're done with it.
      More generally, if you're using a library function (whether it's from the
      standard library or another library) that allocates resources, you need
      to find out how those resources were allocated and how you're expected
      to release them when you're done with them.
      [color=blue]
      >void main()
      >{
      > char line[20] = "abc#def";
      > char * str;
      >
      > str = strtok(line, "#");
      >
      > delete str; // is this necessary?
      > // can I modify the content of the array??
      >}[/color]


      dave

      --
      Dave Vandervies dj3vande@csclub .uwaterloo.ca
      Did you know they sometimes have "int main" threads in
      comp.lang.java. programmer? ... Perhaps we could arrange some kind of
      exchange program... --Richard Heathfield in comp.lang.c

      Comment

      • Dave Vandervies

        #4
        Re: Pointers and Arrays in C

        In article <bns7uc$gie$2@r umours.uwaterlo o.ca>,
        Dave Vandervies <dj3vande@csclu b.uwaterloo.ca> wrote:
        [color=blue]
        >Yes. What you're returning is a pointer to the first element in the
        >array represented by the string literal; unlike the array on the stack
        >in case 1, this will still be there when generateString returns.[/color]

        Before the pedants[1] start beating me over head for this, the "stack"
        I'm referring to is the function-invocation stack. This is typically
        implemented using a hardware stack, but anything that "looks stack-like"
        at the granularity of all-the-automatic-variables-in-a-function is a
        valid way of doing it.


        dave

        [1] CLC++ *does* have pedants, I hope? CLC would be far less interesting
        (and far less informative) without them, and I assume that the same
        goes for here.

        --
        Dave Vandervies dj3vande@csclub .uwaterloo.ca
        Did you know they sometimes have "int main" threads in
        comp.lang.java. programmer? ... Perhaps we could arrange some kind of
        exchange program... --Richard Heathfield in comp.lang.c

        Comment

        • Rolf Magnus

          #5
          Re: Pointers and Arrays in C

          Terence wrote:
          [color=blue]
          > I usually program in Java, so I am a bit confused about usint pointers
          > in C.[/color]

          If your question is about C, you should ask in a C newsgroup instead of
          one about C++. Your questions however mostly apply to C as well as C++.
          [color=blue]
          > I would really appreciate if someone can help me.
          >
          > Case 1:
          > ======
          >
          > // Is this function no good? Since str is a variable created on
          > stack,
          > // I am assuming it will be deallocated immedately after the function
          > returns,
          > // right??
          > char * generateString( )
          > {
          > char str[100] = "abc";
          > return str;
          > }[/color]

          The C++ standard doesn't require it to be stored on a stack. Anyway,
          it's an automatic variable that is destroyed when it goes out of scope,
          which happens when you return from the function. So you must not use
          the returned pointer outside the function. Thus, I'd rather say that
          the memory is deallocated immediately before the function returns or
          exactly at the moment when it returns. The important part is just that
          you cannot use it outside the function.
          [color=blue]
          > Case 2:
          > =====
          >
          > // str is a pointer pointing to a literal
          > // Can I use str just like other char arrays?
          > // How are memory allocated for literals and when are they
          > deallocated?? void main()
          > {
          > char * str;
          > str = "abc";
          > }[/color]

          A literal exists for the whole life time of the program, so you can use
          a pointer to it even outside the function. You can't use it like "other
          char arrays", because you may not write to it. The reason why it's
          allowed to let a pointer to non-const point to it is historical (a
          legacy from C).
          Btw: main must return int.
          [color=blue]
          > Case 3:
          > =====
          >
          > // Similar to case 2 except the literal is returned from a function
          > // Again, can I use str for anything? When is it deleted from
          > memory?? void main()
          > {
          > char * str;
          > str = generateString( );
          > }
          >
          > char * generateString( )
          > {
          > return "abc";
          > }[/color]

          Just as above, the literal exists as long as the program is running, so
          you're free to use it anywhere, but again, you must not write to it.
          Better let generateString return a const char*, so you can't by
          accident write to it.
          [color=blue]
          > Case 4:
          > =====
          >
          > // assigning dynamically allocated array to pointer
          > void main()
          > {
          > char * str;
          > str = generateString( );
          > ...
          > delete str; // I have to delete str at the end, Right?
          > }
          >
          > char * generateString( )
          > {
          > char * charArray = new char[20];
          > strcpy(charArra y, "abc");
          > return charArray;
          > }[/color]

          That's almost correct. If you use new, you need a corresponding delete.
          If you use new[], you need delete[], so your last line of main would
          need to be:

          delete [] str;
          [color=blue]
          > Case 5:
          > =====
          >
          > // str points to a char array created in a C library function
          > // How was this char array allocated? When will it be deallocated?
          > // Do I have to delete it explicitly??
          > void main()
          > {
          > char line[20] = "abc#def";
          > char * str;
          >
          > str = strtok(line, "#");
          >
          > delete str; // is this necessary?
          > // can I modify the content of the array??
          > }[/color]

          strtok doesn't allocate any memory. It modifies the char array you gave
          to it.
          Generally, look into the documentation of a function. It should always
          tell you whether you have to deallocate any memory from it or not.


          Comment

          • Rolf Magnus

            #6
            Re: Pointers and Arrays in C

            Dave Vandervies wrote:
            [color=blue][color=green]
            >>Yes. What you're returning is a pointer to the first element in the
            >>array represented by the string literal; unlike the array on the stack
            >>in case 1, this will still be there when generateString returns.[/color]
            >
            > Before the pedants[1] start beating me over head for this, the "stack"
            > I'm referring to is the function-invocation stack. This is typically
            > implemented using a hardware stack, but anything that "looks
            > stack-like" at the granularity of all-the-automatic-variables-
            > in-a-function is a valid way of doing it.[/color]

            Couldn't an implementation even choose to dynamically allocate the
            automatic variables internally and when they go out of scope, delete
            them again? Not the fastest solution, but valid AFAIK.
            [color=blue]
            > [1] CLC++ *does* have pedants, I hope?[/color]

            I thought all the regulars are pedants, aren't they?
            [color=blue]
            > CLC would be far less interesting (and far less informative) without
            > them, and I assume that the same goes for here.[/color]

            Comment

            • Dave Vandervies

              #7
              Re: Pointers and Arrays in C

              In article <bns9cs$6cf$05$ 1@news.t-online.com>,
              Rolf Magnus <ramagnus@t-online.de> wrote:[color=blue]
              >Dave Vandervies wrote:
              >[color=green][color=darkred]
              >>>Yes. What you're returning is a pointer to the first element in the
              >>>array represented by the string literal; unlike the array on the stack
              >>>in case 1, this will still be there when generateString returns.[/color]
              >>
              >> Before the pedants[1] start beating me over head for this, the "stack"
              >> I'm referring to is the function-invocation stack. This is typically
              >> implemented using a hardware stack, but anything that "looks
              >> stack-like" at the granularity of all-the-automatic-variables-
              >> in-a-function is a valid way of doing it.[/color]
              >
              >Couldn't an implementation even choose to dynamically allocate the
              >automatic variables internally and when they go out of scope, delete
              >them again? Not the fastest solution, but valid AFAIK.[/color]

              Yep, it would be valid, but you'd still end up with something that looks
              stack-like; the first function invoked (or, more precisely, the first
              scope entered) would be the bottom of the stack, and the most recent one
              would be the top. When you enter a scope, you create a new invocation
              record and push it onto the stack; when you leave, you pop and discard
              the record at the top, and return to the scope represented by the next
              record down.

              [color=blue][color=green]
              >> [1] CLC++ *does* have pedants, I hope?[/color]
              >
              >I thought all the regulars are pedants, aren't they?[/color]

              I would be worried if they weren't.


              dave

              --
              Dave Vandervies dj3vande@csclub .uwaterloo.ca
              Did you know they sometimes have "int main" threads in
              comp.lang.java. programmer? ... Perhaps we could arrange some kind of
              exchange program... --Richard Heathfield in comp.lang.c

              Comment

              • Peter van Merkerk

                #8
                Re: Pointers and Arrays in C

                < snipped questions about pointer and C-style string handling>

                Other have answer your questions already. But since you are asking the
                questions in comp.lang.c++ and you are new to C++ (I presume), you might
                be interested in the std::string class. The std::string class makes
                string handling much easier and less error prone compared to C style
                strings; no need to worry about pointers, life time issues, allocating
                sufficient memory...etc. Also string manipulation is much more
                convenient with this class:

                #include <iostream>
                #include <string>
                using namespace std;

                string generateString( string name)
                {
                string str = "Hello " + name + "!";
                return str;
                }

                int main()
                {
                cout << "Your name ? ";
                string name;
                getline(cin, name);
                string msg = generateString( name);
                cout << msg << endl;
                return 0;
                }

                --
                Peter van Merkerk
                peter.van.merke rk(at)dse.nl


                Comment

                Working...