1

I got this weird behavior of my programm, that i cant figure out. My professor showed me a flaw in my programm, where i just copy a char pointer when i construct an object instead of making a new copy of the whole array, so you can fool around with it. He demonstrated this with similar code like this.

For the code:

char sweat[] ="Sweater";
warenkorb = new WareImKorb(new Textil (205366,4.2,sweat,40),2,warenkorb);
sweat[0] = '\0';

now if i instead make it:

char* sweat ="Sweater";

the program runs fine till i try sweat[0] = '\0'; It simply crahes then.

However this works: char cc[] ="Sweater"; char* sweat = cc;

It is really bugging me, that i dont understand, why version 1 does not work. Hope you guys can help me out, or else i will go crazy wondering about this.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
Siniyas
  • 443
  • 1
  • 5
  • 19
  • What does not work about the first version? Why are you using char arrays instead of std::string? – CashCow Feb 15 '11 at 18:00
  • Same question in C: [c - Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s\[\]"? - Stack Overflow](https://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-char-s-initialized-with-a) – user202729 Jun 18 '22 at 10:33

5 Answers5

5

"Sweater" is a string literal, which may reside in read-only memory. Using the char[] syntax copies this literal into a char array, using the char * syntax (which really should be const char *) just points at the original string literal.

Erik
  • 88,732
  • 13
  • 198
  • 189
3
char* sweat ="Sweater";
sweat[0] = '\0'

Here sweat points to a CONSTANT data. "Sweater" is const literal data, residing somewhere in read-only memory, and sweat points to this data as such. It doesn't make a copy of it. So when you do sweat[0]='\0', it tries to change first character of the CONSTANT data. Hence the error. By the way, a good compiler should give warning if you don't write const in your declaration, as const char* sweater = "Sweater". See the warning here : http://www.ideone.com/P47vv

But when you write char sweat[] = "Sweater", an array of char is created, copying the data from the CONSTANT data which is "Sweater"; that array's element itself is modifiable!


Lets see an interesting thing: since in the first case, it doesn't make a copy of the const data, so no matter how many variables you declare (all pointing to the same data), the address would be same for all variables. See this:

#include<cstdio>
int main() {
        char* sweat  ="Sweater";        //notice the warning
        const char* another ="Sweater"; //no warning!
        std::printf("%p\n", sweat);     //print the address
        std::printf("%p\n", another);   //print the address
        return 0;
}

Output:

0x8048610
0x8048610

Means, both printfs print the same address!

See yourself here : http://www.ideone.com/VcyM6

Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

ASCII art to the rescue! The char sweat[] version looks like this in memory:

       +---+---+---+---+---+---+---+---+
sweat: |'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 |   char[8]
       +---+---+---+---+---+---+---+---+

Whereas the char* sweat version looks like this:

       +---+---+---+---+---+---+---+---+
       |'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 |   const char[8]
       +---+---+---+---+---+---+---+---+
         ^
         |
         |
       +-|-+
sweat: | | |   char*
       +---+

That's right, a char* pointing to a const char. The fact that you can assign a string literal to a non-const character pointer is a nasty holy in C++'s static type system. Curse you, backward compatibility!

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
0

In the version that doesn't work, you are not creating any array of chars. You are only playing with pointers.

For sweat[0] = '\0' to be a valid statement, you need sweat to be an actual array of chars.

This is done only with char sweat[] = "XXXX"; or char sweat[20];

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
0

C++ is not a managed language. Avoid creating pointers to character arrays that don't have a proper size. Both of the following examples are better solutions:

char* sweater = new char[10];
sweater[0] = '\0';
delete [] sweater;
sweater = NULL;

Or better yet:

std::string sweater = "";
Zac Howland
  • 15,777
  • 1
  • 26
  • 42