How to create separate character pointers?

Discussion in 'C Programming' started by Lambda, Nov 8, 2007.

  1. Lambda

    Lambda Guest

    I'd like to create separate character pointers,
    pass them to a function to assign each one different value,
    and assign the pointers to an array.

    But when I try:

    #include <stdio.h>
    #include <string.h>

    int main(void)
    {
    int i;

    for (i = 0; i < 5; ++i)
    {
    char *str = "test";
    printf("%p:%s\n", str, str);
    }

    return 0;
    }

    All the pointers refer to the same address.
    When the 'char *str = "test"' is run, no new pointer is created?
     
    Lambda, Nov 8, 2007
    #1
    1. Advertising

  2. Lambda

    Eric Sosman Guest

    Lambda wrote:
    > I'd like to create separate character pointers,
    > pass them to a function to assign each one different value,
    > and assign the pointers to an array.
    >
    > But when I try:
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > int main(void)
    > {
    > int i;
    >
    > for (i = 0; i < 5; ++i)
    > {
    > char *str = "test";
    > printf("%p:%s\n", str, str);
    > }
    >
    > return 0;
    > }
    >
    > All the pointers refer to the same address.
    > When the 'char *str = "test"' is run, no new pointer is created?


    Each execution of the loop creates a new `str' variable.
    Each time, that variable is initialized to point to the same
    "test" string. If your telephone number is written on five
    pieces of paper, it doesn't mean you have five different
    telephones.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 8, 2007
    #2
    1. Advertising

  3. Lambda

    James Kuyper Guest

    Lambda wrote:
    > I'd like to create separate character pointers,
    > pass them to a function to assign each one different value,
    > and assign the pointers to an array.
    >
    > But when I try:
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > int main(void)
    > {
    > int i;
    >
    > for (i = 0; i < 5; ++i)
    > {
    > char *str = "test";
    > printf("%p:%s\n", str, str);
    > }
    >
    > return 0;
    > }
    >
    > All the pointers refer to the same address.
    > When the 'char *str = "test"' is run, no new pointer is created?


    A new pointer object is created each time, though on many
    implementations that new pointer object is likely to be created in
    exactly the same location. The key problem isn't the pointer object,
    it's the pointer value that it's initialized with. When you write a
    string literal such as "test" in contexts like this one, what happens is
    that an unnamed array of 5 characters is created and filled in with 't',
    'e', 's', 't', and '\0'. The string literal is treated as a pointer to
    that array. Therefore, every time you go through the loop, you
    initialize your pointer object with a pointer value that points at the
    same unnamed array.

    The right way to fix this depends very much on what it is that you're
    trying to do. The simplest approach that matches your description would
    be as follows:

    #include <stdio.h>
    int main(void)
    {
    char str1[] = "test";
    char str2[] = "test";
    char str3[] = "test";
    char str4[] = "test";
    char str5[] = "test";
    char *array[5] = {str1, str2, str3, str4, str5};
    int i;

    for(i=0; i<5; ++i)
    printf("%p:%s\n", array, array);
    // Use array.

    return 0;
    }

    Note that in this case the string literals are used to initialize an
    array, not a pointer in an array. In this case, no unnamed array is
    created; instead, each definition creates a separate array and
    initializes that array

    While the above code matches your description, I doubt that it's what
    you really want. The following more complicated case is probably closer
    to what you're looking for:

    #include <stdio.h>
    #include <stdlib.h>
    #define STRINGS 5

    int main(void)
    {
    char *array[STRINGS];
    int i;
    for(i=0; i<STRINGS; i++)
    {
    array = malloc(5);
    if(array)
    {
    strcpy(array, "test");
    printf("%p:%s\n", array, array);
    }
    else
    {
    printf("%p: failed allocation\n", array);
    }
    }

    for(i=0; i<STRINGS; i++)
    free(array);
    return 0;
    }
     
    James Kuyper, Nov 8, 2007
    #3
  4. Lambda

    CBFalconer Guest

    James Kuyper wrote:
    >

    .... snip ...
    >
    > for(i=0; i<5; ++i)
    > printf("%p:%s\n", array, array);
    > // Use array.


    To avoid awkward line wraps, avoid using the // comments in posted
    material. They are also illegal under C90.

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Nov 8, 2007
    #4
  5. Lambda

    James Kuyper Guest

    CBFalconer wrote:
    > James Kuyper wrote:
    > ... snip ...
    >> for(i=0; i<5; ++i)
    >> printf("%p:%s\n", array, array);
    >> // Use array.

    >
    > To avoid awkward line wraps, avoid using the // comments in posted
    > material.


    > They are also illegal under C90.


    I write for the current standard, not the old one. It's been many years
    since I last worked on a system that didn't have a compiler which would
    support at least that much of C99.
     
    James Kuyper, Nov 8, 2007
    #5
  6. Lambda

    Mark Bluemel Guest

    James Kuyper wrote:
    > CBFalconer wrote:
    >> James Kuyper wrote:
    >> ... snip ...
    >>> for(i=0; i<5; ++i)
    >>> printf("%p:%s\n", array, array);
    >>> // Use array.

    >>
    >> To avoid awkward line wraps, avoid using the // comments in posted
    >> material.

    >
    >> They are also illegal under C90.

    >
    > I write for the current standard, not the old one. It's been many years
    > since I last worked on a system that didn't have a compiler which would
    > support at least that much of C99.


    Fair enough, but Chuck's first point still applies. "/* ... */" works
    fine when wrapped by a newsreader, while "//" doesn't

    It's not a problem in the specific code you posted, but in general I'd
    agree with Chuck that "/* ... */" is a better choice for newsgroup postings.
     
    Mark Bluemel, Nov 8, 2007
    #6
  7. Lambda

    Willem Guest

    Eric wrote:
    ) <snip>
    )> for (i = 0; i < 5; ++i)
    )> {
    )> char *str = "test";
    )> printf("%p:%s\n", str, str);
    )> }
    )
    ) Each execution of the loop creates a new `str' variable.
    ) Each time, that variable is initialized to point to the same
    ) "test" string. If your telephone number is written on five
    ) pieces of paper, it doesn't mean you have five different
    ) telephones.

    I bet that even if you wrote printf("%p->%p:%s\n", &str, str, str);
    that you can't find a compiler that wouldn't output the same each
    iteration, although I'm sure the Standard would allow it.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Nov 8, 2007
    #7
  8. Lambda

    Guest

    On Nov 8, 6:43 am, CBFalconer <> wrote:
    > James Kuyper wrote:
    >
    > ... snip ...
    >
    > > for(i=0; i<5; ++i)
    > > printf("%p:%s\n", array, array);
    > > // Use array.

    >
    > To avoid awkward line wraps, avoid using the // comments in posted
    > material. They are also illegal under C90.


    Nice example of why you got to have very thick skin to read this
    group. You don't even need to cast return value of malloc!

    >
    > --
    > Chuck F (cbfalconer at maineline dot net)
    > <http://cbfalconer.home.att.net>
    > Try the download section.
    >
    > --
    > Posted via a free Usenet account fromhttp://www.teranews.com


    Just wonderful. Pure wisdom from Chuck.

    --
    Posted via groups.google.com. It's so much worse than teranews. Yeah!
     
    , Nov 8, 2007
    #8
  9. Lambda

    Coos Haak Guest

    Op Thu, 08 Nov 2007 09:50:54 -0800 schreef :

    > On Nov 8, 6:43 am, CBFalconer <> wrote:
    >> James Kuyper wrote:
    >>
    >> ... snip ...
    >>
    >>> for(i=0; i<5; ++i)
    >>> printf("%p:%s\n", array, array);
    >>> // Use array.

    >>
    >> To avoid awkward line wraps, avoid using the // comments in posted
    >> material. They are also illegal under C90.

    >
    > Nice example of why you got to have very thick skin to read this
    > group. You don't even need to cast return value of malloc!
    >

    Of course not, C isn't C++
    --
    Coos
     
    Coos Haak, Nov 8, 2007
    #9
  10. Lambda

    CBFalconer Guest

    James Kuyper wrote:
    > CBFalconer wrote:
    >> James Kuyper wrote:
    >> ... snip ...
    >>> for(i=0; i<5; ++i)
    >>> printf("%p:%s\n", array, array);
    >>> // Use array.

    >>
    >> To avoid awkward line wraps, avoid using the // comments in posted
    >> material.

    >
    >> They are also illegal under C90.

    >
    > I write for the current standard, not the old one. It's been many
    > years since I last worked on a system that didn't have a compiler
    > which would support at least that much of C99.


    /* .. */ is valid under all systems, and is immune to usenet line
    wrap.

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Nov 8, 2007
    #10
  11. Lambda

    Guest

    CBFalconer wrote:
    > James Kuyper wrote:

    ....
    > > I write for the current standard, not the old one. It's been many
    > > years since I last worked on a system that didn't have a compiler
    > > which would support at least that much of C99.

    >
    > /* .. */ is valid under all systems,


    I restrict myself to the common subset of C90 and C99 only when
    required to compile for C90 (which is true only in my work
    environment). Otherwise, I write C99 code which takes full advantage
    of every feature of C99 that I consider an improvement over C90.

    Don't expect me to follow your coding standards, though I suppose
    there's no way I can stop you from complaining when I violate them.
    However, I would prefer it if you would refrain from doing so. How
    would you feel if I complained every time you posted code that failed
    to take advantage of C99 features that I consider to be improvements?

    > ... and is immune to usenet line
    > wrap.


    I try to avoid posting code examples with lines long enough to wrap.
    If I've failed to achieve that goal, I consider the line length to be
    the problem, not the use of // comments.
     
    , Nov 9, 2007
    #11
  12. Lambda

    CBFalconer Guest

    wrote:
    > CBFalconer wrote:
    >> James Kuyper wrote:

    > ...
    >>> I write for the current standard, not the old one. It's been many
    >>> years since I last worked on a system that didn't have a compiler
    >>> which would support at least that much of C99.

    >>
    >> /* .. */ is valid under all systems,

    >
    > I restrict myself to the common subset of C90 and C99 only when
    > required to compile for C90 (which is true only in my work
    > environment). Otherwise, I write C99 code which takes full advantage
    > of every feature of C99 that I consider an improvement over C90.
    >
    > Don't expect me to follow your coding standards, though I suppose
    > there's no way I can stop you from complaining when I violate them.


    It's not really a complaint, just intended to point out how you can
    avoid nuisances in Usenet. Another point is that the receiver may
    not have a compiler that accepts //. I happen to believe in
    maximizing portability, barring nasty penalties.

    No more need be said about it. Until I forget :)

    --
    Chuck F (cbfalconer at maineline dot net)
    <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Nov 9, 2007
    #12
  13. Lambda

    Eric Sosman Guest

    Willem wrote:
    > Eric wrote:
    > ) <snip>
    > )> for (i = 0; i < 5; ++i)
    > )> {
    > )> char *str = "test";
    > )> printf("%p:%s\n", str, str);
    > )> }
    > )
    > ) Each execution of the loop creates a new `str' variable.
    > ) Each time, that variable is initialized to point to the same
    > ) "test" string. If your telephone number is written on five
    > ) pieces of paper, it doesn't mean you have five different
    > ) telephones.
    >
    > I bet that even if you wrote printf("%p->%p:%s\n", &str, str, str);
    > that you can't find a compiler that wouldn't output the same each
    > iteration, although I'm sure the Standard would allow it.


    The fact that two objects share the same memory location
    at different times in the program's execution does not make
    them the same object.

    Example 1:

    char *p, *q;
    p = malloc(42); /* assume success */
    strcpy (p, "Zaphod");
    free (p);
    q = malloc(21); /* assume success */
    strcpy (q, "Beeblebrox");

    Even if it turns out that p and q refer (during their respective
    periods of validity) to the same address, they do not refer to
    the same object.

    Example 2:

    int f1(void) {
    int i = 42;
    return i;
    }

    int f2(void) {
    int j = 24;
    return j;
    }

    int driver(void) {
    return f1() + f2();
    }

    Even if it turns out that i and j share the same memory location
    they are different objects.

    Perhaps my example of the five pieces of paper would have
    been better if I'd specified that each was burned before the
    next was written.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 9, 2007
    #13
  14. Lambda <> writes:

    > I'd like to create separate character pointers,
    > pass them to a function to assign each one different value,
    > and assign the pointers to an array.
    >
    > But when I try:
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > int main(void)
    > {
    > int i;
    >
    > for (i = 0; i < 5; ++i)
    > {
    > char *str = "test";
    > printf("%p:%s\n", str, str);
    > }
    >
    > return 0;
    > }
    >
    > All the pointers refer to the same address.
    > When the 'char *str = "test"' is run, no new pointer is created?


    You are printing the value of the pointer, which is the address of the
    character literal "test". If the executable were ELF formatted, this
    would most likely be an address in the .rodata section.

    Chip

    --
    Charles M. "Chip" Coldwell
    "Turn on, log in, tune out"
    Somerville, Massachusetts, New England
     
    Chip Coldwell, Nov 9, 2007
    #14
  15. On Nov 9, 11:17 am, wrote:
    > CBFalconer wrote:

    ....
    > > ... and is immune to usenet line wrap.

    >
    > I try to avoid posting code examples with lines long enough to wrap.


    To help with that, here is a little 'Text Width Check'
    tool that I offer.
    <http://www.physci.org/twc.jnlp>

    I recommend keeping line width to less than 62 chars for
    usenet posts.

    --
    Andrew T.
    PhySci.org
     
    Andrew Thompson, Nov 11, 2007
    #15
    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. EvgueniB
    Replies:
    1
    Views:
    655
    Anthony Borla
    Dec 15, 2003
  2. Frank Fredstone
    Replies:
    1
    Views:
    460
    Jean-Francois Briere
    Jun 27, 2006
  3. Elena
    Replies:
    0
    Views:
    900
    Elena
    May 3, 2007
  4. Elena
    Replies:
    0
    Views:
    1,344
    Elena
    May 3, 2007
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    695
Loading...

Share This Page