1

I was trying out some code of Scott Meyers Effective C++, item 3 in particular.

The code in his book should be very similar to this (he left out the constructor)

#include <iostream>


class TextBlock {
public:
    TextBlock(char* ptr) : ptrText(ptr)
    {}
     char& operator[](std::size_t pos) const {
        return ptrText[pos];
    }
private :
    char* ptrText;
};

int main(int argc, char* argv[]) {
    const TextBlock block("Hello");
    std::cout << block[0] << std::endl;
    char* ptr = &block[0];
    *ptr = 'J';
    std::cout << block[0];
}

At the point where I change the contents in the pointer ptr (*ptr = 'J';), I get a segmentation fault (which normally happens when dereferencing an uninitialized or freed pointer). This is not happening here, what is going wrong at *ptr = 'J';

4 Answers4

4

TextBlock does not own any storage. It was pointing at a constant string in memory "Hello" and you've tried to modify the read-only contents.

If you declared a local variable with its own storage, this would work, such as:

char test[32] ;
strcpy( test, "Hello") ;
const TextBlock block( test) ;
char * ptr= &block[0] ;

*ptr= 'J' ;
woolstar
  • 5,063
  • 20
  • 31
1

You should manage

ptrText

member not as a pointer that point to a constant memory region where write is forbidden, but as a reference to a stack-based or heap-based object that you can fully control.

you can use char array instead

#include <iostream>

#define MAX_LENGTH = 1024

class TextBlock {
public:
TextBlock(char* ptr)
{
    memset(ptrText, 0, MAX_LENGTH);
    memcpy(ptrText, ptr, strlen(ptr) < MAX_LENGTH?strlen(ptr):MAX_LENGTH);
}

char& operator[](std::size_t pos) const {
    return ptrText[pos];
}
private :
char ptrText[MAX_LENGTH];

};

Daniel King
  • 407
  • 4
  • 11
0
#include <iostream>


class TextBlock {
public:
    TextBlock(char* ptr) : ptrText(ptr)
    {}
     char& operator[](std::size_t pos) const {
        return ptrText[pos];
    }
private :
    char* ptrText;
};

int main(int argc, char* argv[]) {
    char text[] = "Hello";
    const TextBlock block(text);
    std::cout << block[0] << std::endl;
    char* ptr = &block[0];
    *ptr = 'J';
    std::cout << block[0];
}
michaeltang
  • 2,850
  • 15
  • 18
0

yep this is true! ptrText is just record the ptr of "hello",and "hello" is const static text that you can't change.It didn't store anything~so you can't change it.

jarry
  • 26
  • 2