You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Studio运行C++自定义字符串类代码触发0xC0000005访问违规异常的原因排查

Hey there! Let's break down why you're hitting that access violation error in your mystring class, and fix it step by step.

The Root Causes of the Access Violation

Your error happens because of a few critical issues with how your mystring class manages memory and uses strcat:

  • No independent memory management: Your constructor just assigns the input char* directly to p instead of allocating new memory and copying the string. This means multiple mystring objects can point to the same underlying character array. For example, when you do mystring t1(i); and mystring s2(i);, both t1.p and s2.p point to the same i[100] array on the stack. When you call t1 + s2, strcat(p, z.p) tries to concatenate the array onto itself—strcat has undefined behavior when the source and destination buffers overlap, which leads to memory corruption and access violations.
  • Insufficient buffer space: Even without overlap, if you keep concatenating strings onto a fixed-size stack array (like i[100]), you'll eventually exceed its capacity, causing stack overflow and access violations.
  • Missing essential class functions: You don't have a destructor to free memory (once you start allocating it), a copy constructor, or an assignment operator—this leads to shallow copies and memory leaks or double-free errors later.

Fixed Code with Proper Memory Management

Here's a revised version of your class that fixes these issues, following C++ best practices for string handling:

#include <iostream>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

class mystring {
private:
    char* p;
    int length; // Stores the length of the string (including null terminator)

public:
    // Constructor: Allocate memory and copy input string
    mystring(const char* ps) {
        length = strlen(ps) + 1;
        p = new char[length];
        strcpy(p, ps);
    }

    // Destructor: Free allocated memory to prevent leaks
    ~mystring() {
        delete[] p;
    }

    // Copy constructor: Deep copy to avoid sharing memory
    mystring(const mystring& other) {
        length = other.length;
        p = new char[length];
        strcpy(p, other.p);
    }

    // Assignment operator: Deep copy and handle self-assignment
    mystring& operator=(const mystring& other) {
        if (this != &other) {
            delete[] p; // Free existing memory
            length = other.length;
            p = new char[length];
            strcpy(p, other.p);
        }
        return *this;
    }

    // Overload operator+ for char*: Return a new mystring with concatenated result
    mystring operator+(const char* s) const {
        int newLength = length + strlen(s);
        char* temp = new char[newLength];
        strcpy(temp, p);
        strcat(temp, s);
        mystring result(temp);
        delete[] temp; // Clean up temporary buffer
        return result;
    }

    // Overload operator+ for mystring: Return a new mystring with concatenated result
    mystring operator+(const mystring& z) const {
        int newLength = length + z.length - 1; // Subtract 1 to avoid double-counting null terminator
        char* temp = new char[newLength];
        strcpy(temp, p);
        strcat(temp, z.p);
        mystring result(temp);
        delete[] temp;
        return result;
    }

    // Friend operator+ for char* + mystring
    friend mystring operator+(const char* d, const mystring& s) {
        int newLength = strlen(d) + s.length;
        char* temp = new char[newLength];
        strcpy(temp, d);
        strcat(temp, s.p);
        mystring result(temp);
        delete[] temp;
        return result;
    }

    void print() const {
        cout << p;
    }
};

int main() {
    char t[300] = "def", i[100] = "abc";
    mystring t1(i);
    t1 = t1 + t;
    t1.print();
    cout << endl; // Add newline for readability

    mystring s2(i);
    t1 = t1 + s2;
    t1.print();
    cout << endl;

    mystring s3(i);
    t1 = i + s3;
    t1.print();
    cout << endl;

    return 0;
}

Key Changes Explained

  • Independent memory allocation: The constructor now allocates a new char array for each mystring object, so no two objects share the same memory. This eliminates overlap issues with strcat.
  • Destructor, copy constructor, assignment operator: These ensure proper memory management—no leaks, no double-frees, and no shallow copies.
  • Operator+ returns new objects: Instead of modifying the original mystring (which is counterintuitive for string concatenation, just like std::string), we create a new mystring with the concatenated result. This avoids modifying the original object and prevents unexpected side effects.
  • Const correctness: We added const to parameters and member functions that don't modify the object, which is good practice in C++.

Why This Fixes the Access Violation

By allocating separate memory for each string, we never have overlapping source/destination buffers for strcat. We also calculate the exact size needed for concatenated strings, so we never write beyond the bounds of the allocated memory. All memory is properly managed, so there's no risk of stack overflow or invalid memory access.

内容的提问来源于stack exchange,提问作者Kaiyu Yang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 03:37:38