类里面有结构体数组,类一实例化就有异常,删除数组才没事

大概是这样


#include<iostream>
using namespace std;
struct sc
{
    char* s;
    int d[50];
    int c = 0;
    char a[50][10];
    char* q;
};
struct acsa
{
    char* a;
    int b;
    sc c[50];
};
class se
{
    acsa e[50];
public:

    char* a;
    char* b;
    int c = 0;
    int d = 0;
    int e8;
    int f;
    int g = 0;
};
int main()
{
    se a;
}

会return乱七八糟的
但是把acsa e[50];这条语句也就是类里面的结构体数组注释掉就没关系程序正常return 0,这是为什么呀,应该怎么修改

栈溢出错误,大量的数组成员变量导致栈溢出,把数组开辟在堆区,就可以解决了,修改如下,已运行成功,望采纳

#include<iostream>
#include <string>
using namespace std;
struct sc
{
    char* s;
    int *d = new int[50];
    int c = 0;
    string *str = new string[50];
    char* q;

    ~sc()
    {
        delete[] d;
        delete[] str;
    }
};
struct acsa
{
    char* a;
    int b;
    sc *c = new sc[50];
    ~acsa()
    {
        delete[] c;
    }
};
class se
{

public:
    acsa *e = new acsa[50];
    char* a;
    char* b;
    int c = 0;
    int d = 0;
    int e8;
    int f;
    int g = 0;
    ~se()
    {
        delete[] e;
    }
};
int main()
{
    se a;
    system("pause");
    return 0;
}

关于你的问题,我猜测可能是由于结构体 sc 中使用了指针类型而没有进行初始化,在创建 se 类对象时也就同时创建了其成员变量 e 中的所有数组元素,而这些元素中的指针类型并没有被正确地初始化,导致程序出现异常。

解决这个问题需要在定义指针类型成员变量时给它们分配内存空间,并在析构函数中释放这些空间。另外,可以重载类的拷贝构造函数和赋值运算符来确保类对象的正确复制和赋值。

以下是修改方案示例:

#include<iostream>
#include<cstring>
using namespace std;

struct sc {
    char* s;
    int d[50];
    int c = 0;
    char a[50][10];
    char* q;
    sc() {               // 构造函数,在其中为指针类型成员变量分配内存空间
        s = new char[20];
        memset(s, '\0', 20); // 使用 memset 清空分配的内存
        q = new char[20];
        memset(q, '\0', 20);
    }
    ~sc() {              // 析构函数,在其中释放当前作用域存在的动态内存
        delete[] s;
        delete[] q;
    }
};

struct acsa {
    char* a;
    int b;
    sc c[50];
    acsa() {            // 构造函数,在其中为指针类型成员变量分配内存空间
        a = new char[20];
        memset(a, '\0', 20);
    }
    ~acsa() {           // 析构函数,在其中释放当前作用域存在的动态内存
        delete[] a;
    }
};

class se {
    acsa e[50];

public:
    char* a;
    char* b;
    int c = 0;
    int d = 0;
    int e8;
    int f;
    int g = 0;

    se() {              // 构造函数,为指针类型成员变量分配内存空间
        a = new char[20];
        memset(a, '\0', 20);
        b = new char[20];
        memset(b, '\0', 20);
    }

    ~se() {             // 析构函数,在其中释放当前作用域存在的动态内存
        delete[] a;
        delete[] b;
    }

    // 拷贝构造函数,确保正确复制类对象
    se(const se& other) {
        memcpy(this, &other, sizeof(se));
        for (int i = 0; i < 50; i++) {
            memcpy(&e[i], &other.e[i], sizeof(acsa));
            for (int j = 0; j < 50; j++) {
                e[i].c[j].s = new char[20];
                memcpy(e[i].c[j].s, other.e[i].c[j].s, 20);
                e[i].c[j].q = new char[20];
                memcpy(e[i].c[j].q, other.e[i].c[j].q, 20);
            }
        }
    }

    // 赋值运算符,确保正确赋值类对象
    se& operator=(const se& other) {
        memcpy(this, &other, sizeof(se));
        for (int i = 0; i < 50; i++) {
            memcpy(&e[i], &other.e[i], sizeof(acsa));
            for (int j = 0; j < 50; j++) {
                e[i].c[j].s = new char[20];
                memcpy(e[i].c[j].s, other.e[i].c[j].s, 20);
                e[i].c[j].q = new char[20];
                memcpy(e[i].c[j].q, other.e[i].c[j].q, 20);
            }
        }
        return *this;
    }
};

int main() {
    se a;
}

在这个示例中:

  • 对于结构体 scacsa 中的成员变量,我们通过在它们的构造函数中为指针类型成员变量分配内存空间,并在析构函数中释放这些动态内存来解决引起异常的问题。

  • 对于类 se,我们同样在构造函数和析构函数中为指针类型成员变量分配/释放内存空间。此外,我们还重载了拷贝构造函数和赋值运算符,以确保在复制或者赋值时正确处理指针类型成员变量。

需要注意的是,在实际项目开发的过程中,尤其涉及到动态内存申请和释放时,请务必仔细考虑内存的声明周期,合理分配和释放变量所需的内存空间。(记得给我打赏一点点,谢谢