在 Objective-C++ -> EXC_BAD_ACCESS Error 中使用"new"关键字

Using "new" keyword in Objective-C++ -> EXC_BAD_ACCESS Error

本文关键字:Error 关键字 new ACCESS BAD Objective-C++ gt EXC      更新时间:2023-10-16

在编译器设置为 objective-c++ 的.mm文件上尝试在运行时使用new关键字动态分配 c++ 类对象时,我不知何故遇到了EXC_BAD_ACCESS错误。任何帮助或指导将不胜感激!当我在其本机 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()
: 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   $0x30, %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   $0x8, %rcx
0x1090682c6 <+38>:  movq   -0x10(%rbp), %rsi
0x1090682ca <+42>:  addq   $0x8, %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   $0x20, %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   $0x30, %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   $0x20, %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   $0x20, %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  $0x1, %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   $0x0, -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。在该示例中,您将数组超出 2,而内部循环尝试分配给不存在的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++项目中逐字获取的,那么错误也存在。

相关文章: