Thread: Problem with char arrays

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    52

    Problem with char arrays

    Hi,
    I have a problem with char arrays and pointers. I think it's an obvious begginer issue but I can't figure out why do I get this.
    I have this piece of code in my program:

    Code:
                    char readbuffers[3] = "bbb";
    		char readbuffer[3] = "aaa";
    		printf("%s\n", readbuffer);
    
    
    		char *codCliente = argv[2];
    		char *tipoCliente = argv[3];
    		char *Distancia = argv[7];
    		char *tipoTrayecto = argv[8];
    		printf("%s\n", codCliente);	
    		printf("%s\n", tipoCliente);
    		printf("%s\n", Distancia);
    		printf("%s\n", tipoTrayecto);
    And my output is a seven characters array, aaabbb��

    Why the arrays are automatically appending?

    Thank you in advance.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    "bbb" is a four-character string. So is "aaa". When you try to stuff that four-character string into a three-character array, you lose the fourth character: the "end-of-string" marker \0, which means you no longer have a string (so trying to pretend it is a string, for instance by printing it with %s, is doomed to failure).

  3. #3
    Registered User
    Join Date
    Aug 2007
    Posts
    52
    Oh, thank you very much tabstop. That's right. I was stuck so much time in this silly thing!

  4. #4
    Registered User
    Join Date
    Dec 2010
    Posts
    31

    a tip for static strings

    Quote Originally Posted by JOCAAN View Post
    Oh, thank you very much tabstop. That's right. I was stuck so much time in this silly thing!
    To let the compiler do the counting you can use:

    Code:
            char readbuffer[] = "abc";
    this also works:

    Code:
            char *readbuffer = "abc";

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by kona49er View Post

    this also works:

    Code:
            char *readbuffer = "abc";
    in this case you should declare it as const - since you do not allocate the memory and just have a pointer to the constant string that cannot be modified.

    Code:
            const char *readbuffer = "abc";
    and in the case it is technically not a buffer - so the name would be misguiding
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    52
    Thank you.

  7. #7
    Registered User
    Join Date
    Dec 2010
    Posts
    31
    [QUOTE=vart;992964]in this case you should declare it as const - since you do not allocate the memory and just have a pointer to the constant string that cannot be modified.

    Code:
            const char *readbuffer = "abc";
    Your statement, above, is incorrect.

    Storage in memory must be allocated for it. The difference between:

    Code:
            char *a = "abc";
    and
    Code:
            const char *a ="def";
    the later declares that the storage allocated is not intended to be modified and
    and a error should be displayed when the program attempts to make a change
    to any element of this array.

    with the former, array elements may be modified with impunity.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by kona49er
    Storage in memory must be allocated for it.
    Good catch, but...

    Quote Originally Posted by kona49er
    the later declares that the storage allocated is not intended to be modified and
    and a error should be displayed when the program attempts to make a change
    to any element of this array.
    I think vart's point is that storage is not allocated for an array named readbuffer as readbuffer would merely be a pointer to the first element of a string literal.

    Quote Originally Posted by kona49er
    with the former, array elements may be modified with impunity.
    The point is, the storage allocated is not intended to be modified either way. Whether you declare that the pointer points to a const char or not does not change this as attempting to modify any element of the string literal results in undefined behaviour. It is not generally true that these "array elements may be modified with impunity" if you declare readbuffer as a pointer to non-const char.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Dec 2010
    Posts
    31
    Quote Originally Posted by laserlight View Post
    Good catch, but...


    It is not generally true that these "array elements may be modified with impunity" if you declare readbuffer as a pointer to non-const char.

    Yes, my bad. It does work with gcc but that's not a guarantee.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by kona49er View Post
    Yes, my bad. It does work with gcc but that's not a guarantee.
    It compiles everywhere, gcc or no, since there is no syntax error involved. It runs nowhere (unless you have a system that does not protect string literals, but I am unaware of such).

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by tabstop View Post
    It compiles everywhere, gcc or no, since there is no syntax error involved. It runs nowhere (unless you have a system that does not protect string literals, but I am unaware of such).
    Borland's Turbo C, I believe, lets you modify string literals. I think Adak keeps bringing that point up.


    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    Dec 2010
    Posts
    31
    Quote Originally Posted by tabstop View Post
    It compiles everywhere, gcc or no, since there is no syntax error involved. It runs nowhere (unless you have a system that does not protect string literals, but I am unaware of such).
    The following code runs fine on cygwin compiled with gcc.

    Code:
    #include <stdio.h>
    
    int main()
    {
            char * rb = "hij";
    
            printf("%s \n", rb);
            rb[0] = 'z';
            printf("%s \n", rb);
    }
    But ... due to the enlightenment received from this thread, I will not write the code this way.

  13. #13
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    There are a great number of systems that allow modifying string literals. Many embedded systems don't have a memory management unit that allows memory segmentation, thus you can't mark a segment read-only to protect string literal data. Often in these systems, all memory, including the text section, is writable. Makes debugging pointer problems a nightmare, as there is no seg fault generated when there is no segment or segment rule to violate, so there's nothing for a debugger to trap.

    You also, however, have the issue that certain compilers can/may place string literals in writable memory segments (Turbo C as Quzah/Adak point out). Older versions of gcc had the -fwritable-strings flag that did this, but they dropped it somewhere between version 2.9 and 4.1, realizing it was a bad idea (we had tons of code that relied on that "feature" at my last job. When we upgraded gcc to 4.1, it was a nightmare).

    String literals should never be counted on as being modifiable. If you want to modify the contents of a string literal, you are really asking the compiler to let the data vary at run time, which means the data in the string literal (not the address thereof) should be in a variable, like char[] = "foo". Besides, not all compilers support writable strings, and you don't have a good mechanism for determining the size of the modifiable string you have to work with. Also, guaranteeing that a string literal can't change allows the compiler to optimize for size by having all string literals you use that have identical contents live at the same address, so "abc" exists only once, now matter how many things you make point to it.
    Last edited by anduril462; 01-03-2011 at 10:49 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sending a simple email in C++?
    By Coukapecker in forum C++ Programming
    Replies: 6
    Last Post: 04-09-2010, 12:36 PM
  2. help !! : problem with binary file, and fread into structs
    By stevehicks in forum C Programming
    Replies: 5
    Last Post: 02-14-2010, 10:29 AM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Conversion Char To Char * Problem
    By ltanusaputra in forum Windows Programming
    Replies: 3
    Last Post: 03-01-2008, 02:06 PM
  5. The Interactive Animation - my first released C program
    By ulillillia in forum A Brief History of Cprogramming.com
    Replies: 48
    Last Post: 05-10-2007, 02:25 AM