在 Objective-C++ 中使用 "new" 关键字 -> EXC_BAD_ACCESS 错误
Using "new" keyword in Objective-C++ -> EXC_BAD_ACCESS Error
我在尝试使用 .mm
文件上的 .mm
关键字在运行时动态分配 c++ class 对象时遇到 EXC_BAD_ACCESS 错误设置为 objective-c++。对此的任何帮助或指导将不胜感激!当我在其原生 C++ 项目文件中 运行 这个游戏时,我遇到了零个问题。
#import "GameCode.h"
#include <cstdlib>
#include <chrono>
#include <cassert>
#include <fstream>
#include <iostream>
#import <GameKit/GameKit.h>
#import "GameKitHelper.h"
#import "CardView.h"
#import "MainFunctions.hpp"
@interface GameCode ()<GameKitHelperDelegate>
{
MainFunctions Main;
}
@property (weak, nonatomic) IBOutlet UIView *cardContainerView;
@end
@implementation GameCode
- (void)viewDidLoad
{
// Do any additional setup after loading the view.
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerAuthenticated)
name:LocalPlayerIsAuthenticated object:nil];
[super viewDidAppear:animated];
Pack *pack = new Pack;// delete after game
//Pack *pack = Pack_Maker();
//Pack *pack = [Pack new];
//Pack *pack = [[Pack alloc] init];
默认 Pack 构造函数
Pack::Pack()
: next(0)
{
for (int i = 0; i < PACK_SIZE ; i++)
{
for(int j = 0; j < NUM_SUITS ; j++)
{
//K=7 TO k =0
for(int k = 0; k < NUM_RANKS; k++)
{
cards[i] = Card(RANK_NAMES_BY_WEIGHT[k], SUIT_NAMES_BY_WEIGHT[j]);
cards[i].get_value();
i++;
}
}
}
}
// Suits in order from lowest suit to highest suit.
constexpr const char* const SUIT_NAMES_BY_WEIGHT[] = {
Card::SUIT_SPADES,
Card::SUIT_HEARTS,
Card::SUIT_CLUBS,
Card::SUIT_DIAMONDS
};
使用卡片构造函数
Card::Card(const std::string &rank_in, const std::string &suit_in)
: rank(rank_in), suit(suit_in) {}
我什至尝试制作一个函数来为我动态分配它,但没有用。错误的访问错误似乎发生在默认的卡分配运算符 Card::operator=
中,所以我尝试创建一个自定义分配运算符,但问题仍然存在。
/*
Card & Card::operator=(const Card &that)
{
this->rank = that.get_rank();
this->suit = that.get_suit();
return *this;
}
*/
下面是从 Card::operator=
到 char_traits<char>::assign:
中的致命错误的线程跟踪
`Card::operator=:
0x1090682a0 <+0>: pushq %rbp
0x1090682a1 <+1>: movq %rsp, %rbp
0x1090682a4 <+4>: subq [=18=]x30, %rsp
0x1090682a8 <+8>: movq %rdi, -0x8(%rbp)
0x1090682ac <+12>: movq %rsi, -0x10(%rbp)
0x1090682b0 <+16>: movq -0x8(%rbp), %rax
0x1090682b4 <+20>: movq -0x10(%rbp), %rcx
0x1090682b8 <+24>: movl (%rcx), %edx
0x1090682ba <+26>: movl %edx, (%rax)
0x1090682bc <+28>: movq %rax, %rcx
0x1090682bf <+31>: addq [=18=]x8, %rcx
0x1090682c6 <+38>: movq -0x10(%rbp), %rsi
0x1090682ca <+42>: addq [=18=]x8, %rsi
0x1090682d1 <+49>: movq %rcx, %rdi
0x1090682d4 <+52>: movq %rax, -0x18(%rbp)
0x1090682d8 <+56>: callq 0x1090688f0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator= at string:2303
-> 0x1090682dd <+61>: movq -0x18(%rbp), %rcx
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator=:
0x1090688f0 <+0>: pushq %rbp
0x1090688f1 <+1>: movq %rsp, %rbp
0x1090688f4 <+4>: subq [=19=]x20, %rsp
0x1090688f8 <+8>: movq %rdi, -0x8(%rbp)
0x1090688fc <+12>: movq %rsi, -0x10(%rbp)
0x109068900 <+16>: movq -0x8(%rbp), %rax
0x109068904 <+20>: movq -0x10(%rbp), %rsi
0x109068908 <+24>: movq %rax, %rdi
0x10906890b <+27>: movq %rax, -0x20(%rbp)
0x10906890f <+31>: callq 0x109068920 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__move_assign at string:2291
-> 0x109068914 <+36>: movq -0x20(%rbp), %rax
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__move_assign:
0x109068920 <+0>: pushq %rbp
0x109068921 <+1>: movq %rsp, %rbp
0x109068924 <+4>: subq [=20=]x30, %rsp
0x109068928 <+8>: movq %rdi, -0x10(%rbp)
0x10906892c <+12>: movq %rsi, -0x18(%rbp)
0x109068930 <+16>: movq -0x10(%rbp), %rax
0x109068934 <+20>: movq %rax, %rdi
0x109068937 <+23>: movq %rax, -0x20(%rbp)
0x10906893b <+27>: callq 0x109068990 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__clear_and_shrink at string:3819
-> 0x109068940 <+32>: movq -0x18(%rbp), %rdi
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__clear_and_shrink:
0x109068990 <+0>: pushq %rbp
0x109068991 <+1>: movq %rsp, %rbp
0x109068994 <+4>: subq [=21=]x20, %rsp
0x109068998 <+8>: movq %rdi, -0x8(%rbp)
0x10906899c <+12>: movq -0x8(%rbp), %rax
0x1090689a0 <+16>: movq %rax, %rdi
0x1090689a3 <+19>: movq %rax, -0x10(%rbp)
0x1090689a7 <+23>: callq 0x109068ac0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::clear at string:3061
-> 0x1090689ac <+28>: movq -0x10(%rbp), %rdi
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::clear:
0x109068ac0 <+0>: pushq %rbp
0x109068ac1 <+1>: movq %rsp, %rbp
0x109068ac4 <+4>: subq [=22=]x20, %rsp
0x109068ac8 <+8>: movq %rdi, -0x8(%rbp)
0x109068acc <+12>: movq -0x8(%rbp), %rax
0x109068ad0 <+16>: movq %rax, %rdi
0x109068ad3 <+19>: movq %rax, -0x18(%rbp)
0x109068ad7 <+23>: callq 0x109068ce0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__invalidate_all_iterators at string:1684
0x109068adc <+28>: jmp 0x109068ae1 ; <+33> at string
0x109068ae1 <+33>: movq -0x18(%rbp), %rdi
0x109068ae5 <+37>: callq 0x109068b60 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__is_long at string:1420
0x109068aea <+42>: testb [=22=]x1, %al
0x109068aec <+44>: jne 0x109068af7 ; <+55> at string
0x109068af2 <+50>: jmp 0x109068b22 ; <+98> at string
0x109068af7 <+55>: movq -0x18(%rbp), %rdi
0x109068afb <+59>: callq 0x109068bf0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__get_long_pointer at string:1499
0x109068b00 <+64>: movb [=22=]x0, -0x9(%rbp)
0x109068b04 <+68>: movq %rax, %rdi
0x109068b07 <+71>: leaq -0x9(%rbp), %rsi
0x109068b0b <+75>: callq 0x109068cf0 ; std::__1::char_traits<char>::assign at __string:208
-> 0x109068b10 <+80>: xorl %ecx, %ecx
`std::__1::char_traits<char>::assign:
0x109068cf0 <+0>: pushq %rbp
0x109068cf1 <+1>: movq %rsp, %rbp
0x109068cf4 <+4>: movq %rdi, -0x8(%rbp)
0x109068cf8 <+8>: movq %rsi, -0x10(%rbp)
0x109068cfc <+12>: movq -0x10(%rbp), %rax
0x109068d00 <+16>: movb (%rax), %cl
0x109068d02 <+18>: movq -0x8(%rbp), %rax
-> 0x109068d06 <+22>: movb %cl, (%rax)
您没有提供 cards
的声明和限制常量,但我觉得这个循环很可疑:
for (int i = 0; i < PACK_SIZE ; i++)
{
for(int j = 0; j < NUM_SUITS ; j++)
{
//K=7 TO k =0
for(int k = 0; k < NUM_RANKS; k++)
{
cards[i] = Card(RANK_NAMES_BY_WEIGHT[k], SUIT_NAMES_BY_WEIGHT[j]);
cards[i].get_value();
i++;
}
}
}
我怀疑 i
超出了您的 cards
数组的范围。您在最外层循环的迭代表达式和最内层循环的主体中递增 i
。
假设 NUM_SUITS
是 4 而 NUM_RANKS
是 13,就像在标准纸牌中一样,此代码将在第一次迭代时分配 cards[0]
到 cards[51]
最外层循环,然后跳过 cards[52]
并将 cards[53]
分配给 cards[104]
,跳过 cards[105]
,依此类推。
我预计 cards
的维度可能是 NUM_SUITS * NUM_RANKS
的倍数,例如 156。在那个例子中,当内部循环试图分配给不存在 cards[156]
和 cards[157]
.
我建议也许将最外层循环更改为 while (i < PACK_SIZE)
并在您的代码中放置一些 assert
以确保数组维度和 运行 索引符合您的期望:
int i = 0;
while (i < PACK_SIZE)
{
assert(i + NUM_SUITS * NUM_RANKS <= cards.size());
for(int j = 0; j < NUM_SUITS ; j++)
{
for(int k = 0; k < NUM_RANKS; k++)
{
cards[i] = Card(RANK_NAMES_BY_WEIGHT[k], SUIT_NAMES_BY_WEIGHT[j]);
cards[i].get_value();
i++;
}
}
}
assert(i <= cards.size());
不用说,如果这段代码是从纯 C++ 项目中逐字提取的,那么错误也存在。
我在尝试使用 .mm
文件上的 .mm
关键字在运行时动态分配 c++ class 对象时遇到 EXC_BAD_ACCESS 错误设置为 objective-c++。对此的任何帮助或指导将不胜感激!当我在其原生 C++ 项目文件中 运行 这个游戏时,我遇到了零个问题。
#import "GameCode.h"
#include <cstdlib>
#include <chrono>
#include <cassert>
#include <fstream>
#include <iostream>
#import <GameKit/GameKit.h>
#import "GameKitHelper.h"
#import "CardView.h"
#import "MainFunctions.hpp"
@interface GameCode ()<GameKitHelperDelegate>
{
MainFunctions Main;
}
@property (weak, nonatomic) IBOutlet UIView *cardContainerView;
@end
@implementation GameCode
- (void)viewDidLoad
{
// Do any additional setup after loading the view.
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerAuthenticated)
name:LocalPlayerIsAuthenticated object:nil];
[super viewDidAppear:animated];
Pack *pack = new Pack;// delete after game
//Pack *pack = Pack_Maker();
//Pack *pack = [Pack new];
//Pack *pack = [[Pack alloc] init];
默认 Pack 构造函数
Pack::Pack()
: next(0)
{
for (int i = 0; i < PACK_SIZE ; i++)
{
for(int j = 0; j < NUM_SUITS ; j++)
{
//K=7 TO k =0
for(int k = 0; k < NUM_RANKS; k++)
{
cards[i] = Card(RANK_NAMES_BY_WEIGHT[k], SUIT_NAMES_BY_WEIGHT[j]);
cards[i].get_value();
i++;
}
}
}
}
// Suits in order from lowest suit to highest suit.
constexpr const char* const SUIT_NAMES_BY_WEIGHT[] = {
Card::SUIT_SPADES,
Card::SUIT_HEARTS,
Card::SUIT_CLUBS,
Card::SUIT_DIAMONDS
};
使用卡片构造函数
Card::Card(const std::string &rank_in, const std::string &suit_in)
: rank(rank_in), suit(suit_in) {}
我什至尝试制作一个函数来为我动态分配它,但没有用。错误的访问错误似乎发生在默认的卡分配运算符 Card::operator=
中,所以我尝试创建一个自定义分配运算符,但问题仍然存在。
/*
Card & Card::operator=(const Card &that)
{
this->rank = that.get_rank();
this->suit = that.get_suit();
return *this;
}
*/
下面是从 Card::operator=
到 char_traits<char>::assign:
`Card::operator=:
0x1090682a0 <+0>: pushq %rbp
0x1090682a1 <+1>: movq %rsp, %rbp
0x1090682a4 <+4>: subq [=18=]x30, %rsp
0x1090682a8 <+8>: movq %rdi, -0x8(%rbp)
0x1090682ac <+12>: movq %rsi, -0x10(%rbp)
0x1090682b0 <+16>: movq -0x8(%rbp), %rax
0x1090682b4 <+20>: movq -0x10(%rbp), %rcx
0x1090682b8 <+24>: movl (%rcx), %edx
0x1090682ba <+26>: movl %edx, (%rax)
0x1090682bc <+28>: movq %rax, %rcx
0x1090682bf <+31>: addq [=18=]x8, %rcx
0x1090682c6 <+38>: movq -0x10(%rbp), %rsi
0x1090682ca <+42>: addq [=18=]x8, %rsi
0x1090682d1 <+49>: movq %rcx, %rdi
0x1090682d4 <+52>: movq %rax, -0x18(%rbp)
0x1090682d8 <+56>: callq 0x1090688f0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator= at string:2303
-> 0x1090682dd <+61>: movq -0x18(%rbp), %rcx
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator=:
0x1090688f0 <+0>: pushq %rbp
0x1090688f1 <+1>: movq %rsp, %rbp
0x1090688f4 <+4>: subq [=19=]x20, %rsp
0x1090688f8 <+8>: movq %rdi, -0x8(%rbp)
0x1090688fc <+12>: movq %rsi, -0x10(%rbp)
0x109068900 <+16>: movq -0x8(%rbp), %rax
0x109068904 <+20>: movq -0x10(%rbp), %rsi
0x109068908 <+24>: movq %rax, %rdi
0x10906890b <+27>: movq %rax, -0x20(%rbp)
0x10906890f <+31>: callq 0x109068920 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__move_assign at string:2291
-> 0x109068914 <+36>: movq -0x20(%rbp), %rax
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__move_assign:
0x109068920 <+0>: pushq %rbp
0x109068921 <+1>: movq %rsp, %rbp
0x109068924 <+4>: subq [=20=]x30, %rsp
0x109068928 <+8>: movq %rdi, -0x10(%rbp)
0x10906892c <+12>: movq %rsi, -0x18(%rbp)
0x109068930 <+16>: movq -0x10(%rbp), %rax
0x109068934 <+20>: movq %rax, %rdi
0x109068937 <+23>: movq %rax, -0x20(%rbp)
0x10906893b <+27>: callq 0x109068990 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__clear_and_shrink at string:3819
-> 0x109068940 <+32>: movq -0x18(%rbp), %rdi
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__clear_and_shrink:
0x109068990 <+0>: pushq %rbp
0x109068991 <+1>: movq %rsp, %rbp
0x109068994 <+4>: subq [=21=]x20, %rsp
0x109068998 <+8>: movq %rdi, -0x8(%rbp)
0x10906899c <+12>: movq -0x8(%rbp), %rax
0x1090689a0 <+16>: movq %rax, %rdi
0x1090689a3 <+19>: movq %rax, -0x10(%rbp)
0x1090689a7 <+23>: callq 0x109068ac0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::clear at string:3061
-> 0x1090689ac <+28>: movq -0x10(%rbp), %rdi
`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::clear:
0x109068ac0 <+0>: pushq %rbp
0x109068ac1 <+1>: movq %rsp, %rbp
0x109068ac4 <+4>: subq [=22=]x20, %rsp
0x109068ac8 <+8>: movq %rdi, -0x8(%rbp)
0x109068acc <+12>: movq -0x8(%rbp), %rax
0x109068ad0 <+16>: movq %rax, %rdi
0x109068ad3 <+19>: movq %rax, -0x18(%rbp)
0x109068ad7 <+23>: callq 0x109068ce0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__invalidate_all_iterators at string:1684
0x109068adc <+28>: jmp 0x109068ae1 ; <+33> at string
0x109068ae1 <+33>: movq -0x18(%rbp), %rdi
0x109068ae5 <+37>: callq 0x109068b60 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__is_long at string:1420
0x109068aea <+42>: testb [=22=]x1, %al
0x109068aec <+44>: jne 0x109068af7 ; <+55> at string
0x109068af2 <+50>: jmp 0x109068b22 ; <+98> at string
0x109068af7 <+55>: movq -0x18(%rbp), %rdi
0x109068afb <+59>: callq 0x109068bf0 ; std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__get_long_pointer at string:1499
0x109068b00 <+64>: movb [=22=]x0, -0x9(%rbp)
0x109068b04 <+68>: movq %rax, %rdi
0x109068b07 <+71>: leaq -0x9(%rbp), %rsi
0x109068b0b <+75>: callq 0x109068cf0 ; std::__1::char_traits<char>::assign at __string:208
-> 0x109068b10 <+80>: xorl %ecx, %ecx
`std::__1::char_traits<char>::assign:
0x109068cf0 <+0>: pushq %rbp
0x109068cf1 <+1>: movq %rsp, %rbp
0x109068cf4 <+4>: movq %rdi, -0x8(%rbp)
0x109068cf8 <+8>: movq %rsi, -0x10(%rbp)
0x109068cfc <+12>: movq -0x10(%rbp), %rax
0x109068d00 <+16>: movb (%rax), %cl
0x109068d02 <+18>: movq -0x8(%rbp), %rax
-> 0x109068d06 <+22>: movb %cl, (%rax)
您没有提供 cards
的声明和限制常量,但我觉得这个循环很可疑:
for (int i = 0; i < PACK_SIZE ; i++)
{
for(int j = 0; j < NUM_SUITS ; j++)
{
//K=7 TO k =0
for(int k = 0; k < NUM_RANKS; k++)
{
cards[i] = Card(RANK_NAMES_BY_WEIGHT[k], SUIT_NAMES_BY_WEIGHT[j]);
cards[i].get_value();
i++;
}
}
}
我怀疑 i
超出了您的 cards
数组的范围。您在最外层循环的迭代表达式和最内层循环的主体中递增 i
。
假设 NUM_SUITS
是 4 而 NUM_RANKS
是 13,就像在标准纸牌中一样,此代码将在第一次迭代时分配 cards[0]
到 cards[51]
最外层循环,然后跳过 cards[52]
并将 cards[53]
分配给 cards[104]
,跳过 cards[105]
,依此类推。
我预计 cards
的维度可能是 NUM_SUITS * NUM_RANKS
的倍数,例如 156。在那个例子中,当内部循环试图分配给不存在 cards[156]
和 cards[157]
.
我建议也许将最外层循环更改为 while (i < PACK_SIZE)
并在您的代码中放置一些 assert
以确保数组维度和 运行 索引符合您的期望:
int i = 0;
while (i < PACK_SIZE)
{
assert(i + NUM_SUITS * NUM_RANKS <= cards.size());
for(int j = 0; j < NUM_SUITS ; j++)
{
for(int k = 0; k < NUM_RANKS; k++)
{
cards[i] = Card(RANK_NAMES_BY_WEIGHT[k], SUIT_NAMES_BY_WEIGHT[j]);
cards[i].get_value();
i++;
}
}
}
assert(i <= cards.size());
不用说,如果这段代码是从纯 C++ 项目中逐字提取的,那么错误也存在。