C++ 初始化 Class 段错误

C++ Initialize Class Segmentation Fault

编辑 -- 我更新了 class 代码:

#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);
}

我正在尝试实现一个 class 对象数组,并且 class 没有空构造函数。当我尝试初始化第一个元素时出现分段错误。

声明和设置数组,

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;

}

class:

#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);
}

我可以修改 class 并添加一个空构造函数,但我不想这样做,以确保在初始化时始终使用 C 字符串。

这是在 Linux 32 位 g++ 中编译的。

-马特

您的标题文字 " Main Title Here " 的长度为 41,即 40 个字符 + 字符串终止符,但您只保留了 40 个字节。所以你是一个关闭,应该保留 41 个字节。

尝试:

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

输出:

41

另一个问题是您将 menuItems 声明为指向 MenuItem 的指针类型。然后,使用 *menuItem[0],您取消引用未初始化的指针,因此指向无效的 object。这是段错误的根本原因。

您可以将 menuItem 声明为 MenuItem 的数组,但是 MenuItem 将需要默认构造函数。另一种选择是保留 "pointer to pointer"-隐喻并将指针分配给使用 new:

创建的 object
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-style 与 C++ 混合使用。我建议深入 C++ 的世界并使用 std::vectornewdelete、...并摆脱 mallocfree。 还考虑使用 std::string; "small" 内存管理错误导致的很多问题根本不会出现...