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::vector
、new
、delete
、...并摆脱 malloc
和 free
。
还考虑使用 std::string
; "small" 内存管理错误导致的很多问题根本不会出现...
编辑 -- 我更新了 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
:
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::vector
、new
、delete
、...并摆脱 malloc
和 free
。
还考虑使用 std::string
; "small" 内存管理错误导致的很多问题根本不会出现...