C 初始化类分割故障

C++ Initialize Class Segmentation Fault

本文关键字:故障 分割 初始化      更新时间:2023-10-16

编辑 - 我更新了类代码:

#include "MenuItem.h"
#include <string.h>
MenuItem::MenuItem(const char* txt, const int len)
{
    this->InitText(txt, len);
}
MenuItem::~MenuItem()
{
    delete[] Text;    
}
void MenuItem::InitText(const char* txt, const int len)
{
    Text = new char[len];
    strcpy(Text, txt);
}
void MenuItem::ResetText(const char* txt, const int len)
{
    if (len)
    {
        if (Text)
        {
            delete[] Text;           
        }
        Text = new char[len];
    }
    strcpy(Text, txt);
}

我正在尝试实现一系列类对象和类没有空的构造函数。当我尝试初始化第一个元素时,我会得到一个分段错误。

要声明并设置数组,

MenuItem **menuItems;
menuItems = (MenuItem**) malloc(sizeof (MenuItem) * 8);

在我的主要方法中,我有:

#include "MainApp.h"
#include <iostream>
using namespace Main_App;
int main(int argc, char** argv) {
    MenuItem **menuItems;
    const char title[] = "         Main Title Here                ";
    const char menu1[] = "  1)  Item One                          ";
    const char menu2[] = "  2)  Item Two                          ";
    const char menu3[] = "  3)  Item Three                        ";
    const char menu4[] = "  4)  Item Four                         ";
    const char menu5[] = "  5)  Help                              ";
    const char menu6[] = "  6)  Exit                              ";
    menuItems = (MenuItem**) malloc(sizeof (MenuItem) * 8);

    *menuItems[0] = MenuItem(title, 40); /*<== segmentation fault occurs here */
    *menuItems[1] = MenuItem(menu1, 40);
    *menuItems[2] = MenuItem(menu2, 40);
    *menuItems[3] = MenuItem(menu3, 40);
    *menuItems[4] = MenuItem(menu4, 40);
    *menuItems[5] = MenuItem(menu5, 40);
    *menuItems[6] = MenuItem(menu6, 40);
    *menuItems[7] = MenuItem("", 40);
    for (int i = 0; i < 8; i++) {
        puts(menuItems[i]->Text);
    }
    printf("At main(). Menu App exiting.n");
    return 0;
}

类:

#ifndef MENUITEM_H
#define MENUITEM_H
#include "malloc.h"
class MenuItem {
public:
    MenuItem(const char* txt, const int len);
    ~MenuItem();
    void ResetText(const char* txt, const int len = 0);     
    char *Text;
private:
    void InitText (const char* txt, const int len);
};
#endif /* MENUITEM_H */
/**  MenuItem.cpp file */
#include "MenuItem.h"
#include <string.h>
MenuItem::MenuItem(const char* txt, const int len) {
    this->InitText(txt, len);
}
MenuItem::~MenuItem() {
    if (Text) {
        free(Text);
    }
}
void MenuItem::InitText(const char* txt, const int len) {
    Text = (char*) malloc(len);
    strcpy(Text, txt);
}
void MenuItem::ResetText(const char* txt, const int len) {
    if (len) {
        if (Text) {
            free(Text);            
        }
        Text = (char*) malloc(len);
    }
    strcpy(Text, txt);
}

我可以修改类并添加一个空构造函数,但我希望不这样做,以确保在初始化中始终使用C弦。

这是在Linux 32位G 中编译的。

-matt

您的标题字面的" Main Title Here "41,即40字符 字符串终止字符,但您只保留40个字节。因此,您是一个关闭,应该保留41个字节。

尝试:

int main() {
    char l[] = "         Main Title Here                ";
    printf("%ld",sizeof(l));
}

输出:

41

另一个问题是,您将menuItems声明为指向MenuItem指针的类型指针。然后,使用*menuItem[0],您可以放置一个未初始化的指针,因此指向无效的对象。这就是SEG故障的根本原因。

您可以将menuItem声明为MenuItem s的数组,但是MenuItem需要一个默认的构造函数。另一个选择是将"指向指针指向指针" - 磁极指标,并将指针分配给使用new创建的对象:

menuItems = (MenuItem**) malloc(sizeof (MenuItem*) * 8);
menuItems[0] = new MenuItem(title, 40);
menuItems[1] = new MenuItem(menu1, 40);
menuItems[2] = new MenuItem(menu2, 40);
menuItems[3] = new MenuItem(menu3, 40);
menuItems[4] = new MenuItem(menu4, 40);
menuItems[5] = new MenuItem(menu5, 40);
menuItems[6] = new MenuItem(menu6, 40);
menuItems[7] = new MenuItem("", 40);

无论如何,您将C风格与C 混合。我建议潜入C 的世界,并使用std::vectornewdelete,...并摆脱mallocfree。还要考虑使用std::string;内存管理中的"小"错误都不会出现很多问题...