C ++初始化类分段错误

时间:2017-10-02 17:55:13

标签: c++

编辑 - 我更新了类代码:

#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

1 个答案:

答案 0 :(得分:3)

您的标题文字" 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的数组,但是MenuItem则需要默认构造函数。另一种选择是将指针指向&#34; -metaphor并指定指向使用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,...并摆脱malloc和{{1} }。 还要考虑使用free;很多问题来自&#34;小&#34;记忆管理中的错误根本就不会出现......