0

I get an access violation error when I use a self written Buffer class:

template<typename T> 
class Buffer {
public:
    Buffer(T *data, size_t len);
    Buffer(size_t len);

    size_t len();

    operator T*();
    T& operator[] (const int x) const {
        return this->data[x];
    };

private:
    T *data;
    size_t _len;
};

int main() {
    Buffer<char> b("123", 3);
    b[0] = 0; // This line causes "Access violation writing location 0x003c8830".

    return 0;
}

Why is that? What am I doing wrong?

Xeo
  • 129,499
  • 52
  • 291
  • 397
Erik
  • 11,944
  • 18
  • 87
  • 126
  • 2
    Removed `[c]` tag, this is clearly C++. Next, we won't know how that happened until we see the constructors, but I have a vague idea... – Xeo May 30 '12 at 11:06
  • 1
    String literals are read only, guessing the constructor just points to the string passed in. Can you post the constructor definitions? – hmjd May 30 '12 at 11:07
  • you should allocate memory for `data` – triclosan May 30 '12 at 11:08

4 Answers4

1

The code that causes the issue is not in the post, but it's very likely your constructor: if you assign the pointer data to the member data, then you store the string constant inside your class. Then code of the main than tries to write into non-writable memory, causing access violation.

You can fix your constructor to avoid this problem:

Buffer(T *dataIn, size_t len) {
    data = new T[len];
    memcpy(data, dataIn, len*sizeof(T));
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

"123" is a string literal stored in read only memory,
When you do:

b[0] = 0

You are trying to write to the read only memory thus invoking Undefined Behavior.

You need to allocate dynamic memory to data so that it owns the memory and your code then modify's the owned memory and not the non writable memory which it does not own.
Also, Do make sure You follow the Rule of Three.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

String literals such as "123" are non-writeable. You attempt to assign a value to it when you do b[0] = 0;

In addition, string literals have a terminating NULL character, making that 4 long.

You can specialize you constructor to copy const char inputs.

std''OrgnlDave
  • 3,912
  • 1
  • 25
  • 34
1

You don't show the definition of the constructor, but I bet you're using the assignment operator to copy the C string to Buffer::data. You instead need to use strcpy(). Also, you'll need to allocate 3 + 1 bytes for Buffer::data to ensure that you have enough room for the nul terminator.

chrisaycock
  • 36,470
  • 14
  • 88
  • 125