Access Violation Reading Location when assigning Float (0x0000000000000170) - c++

I'm crashing with a Access Violation reading location. I'm doing this in Unreal Engine, but it's simple and I feel the issue should be universally applicable within C++, though I am new to it.
I am crashing when trying to assign LastDoorOpenTime in OpenDoor() of OpenDoor.cpp (below). I'm able assign to it successfully at the start of the program in UOpenDoor::BeginPlay(), but trying the same thing in OpenDoor() crashes the application with "Access Violation reading location".
OpenDoor.h:
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GameFramework/Actor.h"
#include "Engine/TriggerVolume.h"
#include "Engine/World.h"
#include "OpenDoor.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ESCAPEROOM_API UOpenDoor : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UOpenDoor();
protected:
// Called when the game starts
virtual void BeginPlay() override;
void OpenDoor();
void CloseDoor();
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
UPROPERTY(VisibleAnywhere)
float OpenAngle = -60.f;
UPROPERTY(EditAnywhere)
ATriggerVolume* PressurePlate;
UPROPERTY(EditAnywhere)
float DoorCloseDelay = 1.f;
float LastDoorOpenTime;
AActor* ActorThatOpens;
AActor* Owner;
bool IsDoorOpen;
UWorld* ThisWorld;
};
OpenDoor.cpp:
#include "OpenDoor.h"
// Sets default values for this component's properties
UOpenDoor::UOpenDoor()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void UOpenDoor::BeginPlay()
{
Super::BeginPlay();
ThisWorld = GetWorld();
ActorThatOpens = ThisWorld->GetFirstPlayerController()->GetPawn();
AActor* Owner = GetOwner();
IsDoorOpen = false;
}
void UOpenDoor::OpenDoor()
{
Owner->SetActorRotation(FRotator(0.f, OpenAngle, 0.f));
int cow = 1 + 1;
LastDoorOpenTime = 0.f; //ACCESS VIOLATION HERE
IsDoorOpen = true;
}
void UOpenDoor::CloseDoor()
{
Owner->SetActorRotation(FRotator(0.f, 0.f, 0.f));
IsDoorOpen = false;
}
// Called every frame
void UOpenDoor::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (PressurePlate->IsOverlappingActor(ActorThatOpens)) {
OpenDoor();
}
if (IsDoorOpen) {
if (ThisWorld->GetTimeSeconds() >= LastDoorOpenTime + DoorCloseDelay) {
CloseDoor();
}
}
}

Changing: "AActor* Owner = GetOwner();" to "Owner = GetOwner();" fixed it.

Related

Faster every Frame/Second UnrealEngine C++

MyPawn.cpp
// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Handle growing and shrinking based on our "Grow" action
{
float CurrentScale = OurVisibleComponent->GetComponentScale().X;
if (bGrowing)
{
// Grow to double size over the course of one second
CurrentScale = CurrentScale + 2;
}
else
{
// Shrink half as fast as we grow
CurrentScale -= (DeltaTime * 0.5f);
}
// Make sure we never drop below our starting size, or increase past double size.
CurrentScale = FMath::Clamp(CurrentScale, 1.0f, 2.0f);
OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale));
}
// Handle movement based on our "MoveX" and "MoveY" axes
{
if (!CurrentVelocity.IsZero())
{
FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
SetActorLocation(NewLocation);
}
}
}
MyPawn.h
#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"
UCLASS()
class MYPROJECT_API AMyPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AMyPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(EditAnywhere)
USceneComponent* OurVisibleComponent;
//Input functions
void Move_XAxis(float AxisValue);
void Move_YAxis(float AxisValue);
void StartGrowing();
void StopGrowing();
//Input variables
FVector CurrentVelocity;
bool bGrowing;
};
I want to add a statement that make my Spawn move faster every Frame or Second while one of the key input pressed (Forward,Backward,Left or Right),
I've tried to add
CurrentVelocity.X += CurrentVelocity.X
or
CurrentVelocity.X += 1
in the AMyPawn::Tick, and tried some more combination with no success, hope u can help me solve this .

EXCEPTION_ACCESS_VIOLATION when using RandomPointInBoundingBox method of KismetLibrary

I am facing an issue while generating a random point in a volume using KismetLibrary,
there is the code
#include "Spawner.h"
#include "Components/BoxComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "BaseCell.h"
// Sets default values
ASpawner::ASpawner()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SpawningVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawnVolumeBox"));
RootComponent = SpawningVolume;
Cell = ABaseCell::StaticClass();
}
// Called when the game starts or when spawned
void ASpawner::BeginPlay()
{
Super::BeginPlay();
SpawnCells();
}
// Called every frame
void ASpawner::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ASpawner::SpawnCells()
{
if(Cell != NULL)
{
UWorld* const World = GetWorld();
if (World) {
FVector Origin = SpawningVolume->Bounds.Origin;
FVector Extent = SpawningVolume->Bounds.BoxExtent;
FVector SpawnLocation = UKismetMathLibrary::RandomPointInBoundingBox(Origin, Extent);
FRotator SpawnRotation;
SpawnRotation.Pitch = FMath::FRand() * 360.0f;
SpawnRotation.Roll = FMath::FRand() * 360.0f;
SpawnRotation.Yaw = FMath::FRand() * 360.0f;
ABaseCell* SpawnedCell = World->SpawnActor<ABaseCell>(Cell, SpawnLocation, SpawnRotation);
}
}
}
I should be able to generate without using Kismet the random point but i thought if this kind of library exists we should use them...
it's throwing the following error: https://i.stack.imgur.com/6nG45.png
EDIT
when trying to debug i figured that actually it's when i'm accessing private property "SpawningVolume" that error is thrown... still can't figure why
here is the Spawner.h
#include "BaseCell.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Spawner.generated.h"
UCLASS()
class LIFE_API ASpawner : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ASpawner();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Spawnable
UPROPERTY(EditAnyWhere, category="Spawning")
TSubclassOf<class ABaseCell> Cell;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
private:
// SpawningVolume as BoxComponent
UPROPERTY(VisibleAnyWhere, category="Spawning", meta=(AllowPrivateAccess="true"))
class UBoxComponent* SpawningVolume;
void SpawnCells();
};
EDIT 2
Just added this condition and it seems that "SpawningVolume" is "nullptr" so i don't know what i'm doing wrong but i keep investigating
void ASpawner::SpawnCells()
{
if(Cell != NULL)
{
UWorld* const World = GetWorld();
if (World) {
// Added condition
if (SpawningVolume != nullptr) {
FVector Origin = SpawningVolume->Bounds.Origin;
FVector Extent = SpawningVolume->Bounds.BoxExtent;
FVector SpawnLocation = UKismetMathLibrary::RandomPointInBoundingBox(Origin, Extent);
FRotator SpawnRotation;
SpawnRotation.Pitch = FMath::FRand() * 360.0f;
SpawnRotation.Roll = FMath::FRand() * 360.0f;
SpawnRotation.Yaw = FMath::FRand() * 360.0f;
ABaseCell* SpawnedCell = World->SpawnActor<ABaseCell>(Cell, SpawnLocation, SpawnRotation);
}
}
}
}
ERROR
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x000000000000012c
UE4Editor_Life_0001!ASpawner::SpawnCells() [C:\Users\Benja\OneDrive\Documents\Unreal Projects\Life\Source\Life\Spawner.cpp:46]

b2Shape is equal to 0xCDCDCDCD and thows an exception at Create Fixture

I am following the manual at http://box2d.org/manual.pdf to try and better understand how Box2D works but I have run into a problem. When I call
m_body->CreateFixture it throws an exception when it tries to access the fixtureDef->shape because fixtureDef->shape is 0xCDCDCDCD. I am very confused because I am still learning Box2D and would love it if anyone could help explain.
Here are some important pieces of code to know from PhysicsEngine.h:
class PhysicsGround{
private:
b2Body* m_body;
b2Fixture* m_fixture;
b2PolygonShape m_shape;
public:
void init(glm::vec2 pos, glm::vec2 size, b2World* world);
b2Body* getBody();
void setBody(b2Body* body);
b2Fixture* getFixture();
};
class PhysicsEngine
{
private:
ICMEM::StackAllocator m_stackAlloc;
std::vector<PhysicsSprite*> m_physObjs;
b2World* m_world;
b2Vec2 m_gravity;
public:
PhysicsEngine() {}
void init(float gravX, float gravY);
void shutDown();
void addPhysicsObject(PhysicsSprite* sprite);
void addGround(glm::vec2 pos, glm::vec2 size);
void setGravity(float gravX, float gravY);
void update(double dt);
b2World* getWorld() { return m_world; }
};
Here is some important info from PhysicsEngine.cpp:
void PhysicsEngine::init(float gravX, float gravY) {
m_stackAlloc.init(200000000);
m_world = (b2World*)m_stackAlloc.allocAligned(sizeof(b2World), alignof(b2World));
m_world = new(m_world)b2World(b2Vec2(gravX, gravY));
}
void PhysicsEngine::addGround(glm::vec2 pos, glm::vec2 size) {
PhysicsGround* physicsGround = (PhysicsGround*)m_stackAlloc.allocAligned(sizeof(PhysicsGround), alignof(PhysicsSprite));
physicsGround->init(pos, size, m_world);
}
void PhysicsGround::init(glm::vec2 pos, glm::vec2 size, b2World* world) {
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(pos.x, pos.y);
m_body = world->CreateBody(&groundBodyDef);
m_shape.SetAsBox(size.x / 2.0f, size.y / 2.0f);
m_fixture = m_body->CreateFixture(&m_shape, 0.0f); // Exception thrown here
}
You have uninitialized values in your objects. This creates in non debug build random values, in this case the pattern 0xCDCDCDCD is a typical Visual Studio debug value for these uninitialized values.
You may want to use C++11 initialization capabilities as you don't provide a custom constructor. For instance:
class PhysicsGround{
private:
b2Body* m_body{nullptr};
b2Fixture* m_fixture{nullptr};
b2PolygonShape m_shape;
//
};

Cocos2d retain() in inherited classes

So I've had a lot of trouble with Cocos2d's auto-release shenanigans, and (almost) wish that I could just handle all of that myself...
Anyways, the problem I've had is with creating some animations. I've got a class called AnimatedDamageableSprite which inherits from DamageableSprite which inherits from Sprite which inherits from CCSprite etc...
When I create an AnimatedDamageableSprite, I have a successful animation on the screen, which runs as it should.
When I create a Suicider, which (you guessed it) inherits from AnimatedDamageableSprite, the CCArray which contains the frames for animation doesn't survive beyond the first loop, and on the second update attempt, the program gets an AV error.
Here's the code for the two classes:
Sprite.h
// This class works
class AnimatedDamageableSprite :public DamageableSprite {
public:
AnimatedDamageableSprite(int hp, CCPoint pos, CCTexture2D* tex, int rows, int columns, float scaleX, float scaleY);
virtual ~AnimatedDamageableSprite();
virtual void update(float dt);
virtual bool updateFrame(float dt);
virtual SpriteType getType() { return ANIMATED_DAMAGEABLE_SPRITE; };
protected:
float m_frameNum;
CCArray* m_frames;
int m_numOfFrames;
};
// This class doesn't
class Suicider :public AnimatedDamageableSprite {
public:
Suicider(int difficulty);
virtual ~Suicider();
virtual void update(float dt);
virtual SpriteType getType() { return SUICIDER; };
private:
float m_speed;
};
Sprite.cpp
AnimatedDamageableSprite::AnimatedDamageableSprite(int hp, CCPoint pos, CCTexture2D* tex, int rows, int columns, float scaleX, float scaleY)
:DamageableSprite(hp, pos, tex, scaleX, scaleY), m_frameNum(0), m_numOfFrames(rows*columns) {
float texWidth = tex->getContentSize().width / (float)columns;
float texHeight = tex->getContentSize().height / (float)rows;
m_frames = CCArray::createWithCapacity(m_numOfFrames);
m_frames->retain();
for (unsigned int i = 0; i < columns; i++) {
for (unsigned int j = 0; j < rows; j++) {
CCRect r(i*texWidth, j*texHeight, texWidth, texHeight);
m_frames->addObject(new CCSpriteFrame);
((CCSpriteFrame*)m_frames->lastObject())->createWithTexture(tex, r);
((CCSpriteFrame*)m_frames->lastObject())->initWithTexture(tex, r);
m_frames->lastObject()->retain();
}
}
initWithSpriteFrame((CCSpriteFrame*)m_frames->objectAtIndex(m_frameNum));
setTexture(tex);
setPosition(pos);
setScaleX(scaleX);
setScaleY(scaleY);
updateTransform();
}
// This function is called every frame. It returns a boolean for unrelated reasons
bool AnimatedDamageableSprite::updateFrame(float dt) {
bool retVal = false;
// Assume animations are at 30 FPS for now
m_frameNum += dt * 0.03f;
while (m_frameNum >= m_numOfFrames) {
m_frameNum -= m_numOfFrames;
retVal = true;
}
setDisplayFrame((CCSpriteFrame*)m_frames->objectAtIndex(m_frameNum));
updateTransform();
return retVal;
}
// This class calls the constructor of the one that works, and does nothing else relevant to the problem
// It also doesn't override the updateImage() function
Suicider::Suicider(int difficulty)
: AnimatedDamageableSprite(1, CCPoint(10,10), g_textureManager.getTexture("Suicider Sheet"), 6, 10, SCALE_WIDTH, SCALE_HEIGHT) {
// ...
}
EDIT:
Seems I forgot to actually point out the problem.
The CCArray* m_frames declared in AnimatedDamageableSprite is fine when used in that instance, but it is deleted at the end of a frame when used in the Suicider class - i.e. it isn't being retained. Hence the AV error when I try to access an item inside it which no-longer exists
I tried retaining it in the Suicider constructor as well, although that didn't change anything.

Calling pure virtual function on Box2D GetUserData's result

First of all, I use Cocos2d-x-2.1.5 and Box2D 2.3.0 (not pretty sure how to check which exactly, but found that info on cocos' repository).
My problem appears when I try to call the pure virtual function from the object which was assigned to the b2Body object via SetUserData method.
I scheduled a method updateBodies to update sprites which are the part of my game object's representation.
void GameplayLogicLayer::updateBodies(float pDeltaTime)
{
mWorld->Step(pDeltaTime, 10, 10);
for(b2Body* tBodies = mWorld->GetBodyList(); tBodies; tBodies = tBodies->GetNext()){
A* tA = (static_cast<A*>(tBodies->GetUserData()));
if(tA != NULL)
{
tA->callPureVirtualFunction();
tA->callFunction();
}
}
}
The program crashes when it tries to execute callPureVirtualMethodFunction().
My hierarchy of objects is below (A contains mBody, which is b2Body type; B and C extends A):
In the constructors of B and C I create Box2D body and link the object to the b2Body by:
mBody = pWorld.CreateBody(&tBodyDef);
mBody->SetUserData(this);
Do you have an idea how it crashes while executing pure virtual function, but works well when I call methods from the base class?
EDIT - in response to LearnCocos2d user.
Here is the A class content.
#ifndef __A_H__
#define __A_H__
#include "cocos2d.h"
#include "Box2D/Box2D.h"
USING_NS_CC;
class A
{
public:
virtual void callPureVirtualFunction() = 0;
void callFunction();
protected:
CCSprite* mSprite;
b2Body* mBody;
b2Fixture* mFixture;
};
#endif // __A_H__
And C class implementation.
.h file:
#ifndef __C_H__
#define __C_H__
#include "A.h"
class C : public A
{
public:
C(CCLayer& pParent, b2World& pWorld, const char* pFileName, float pPositionX, float pPositionY, float pWidth, float pHeight);
C();
virtual void callPureVirtualFunction();
private:
bool mWithSensor;
};
#endif // __C_H__
.cpp file:
#include "C.h"
#include "../Utilities/Constants.h"
C::C(CCLayer& pParent, b2World& pWorld, const char* pFileName, float pPositionX, float pPositionY, float pWidth, float pHeight)
{
mWithSensor = false;
// GRAPHICS
if(pFileName)
{
mSprite = CCSprite::create(pFileName);
mSprite->setPosition(CCPointMake(pPositionX, pPositionY));
pParent.addChild(mSprite);
}
b2BodyDef tBodyDef;
tBodyDef.type = b2_kinematicBody;
tBodyDef.position.Set( pPositionX / PIXELS_IN_METER, pPositionY / PIXELS_IN_METER );
// tCollisionBoxBodyDef.userData = this;
tBodyDef.userData = NULL;
mBody = pWorld.CreateBody(&tBodyDef);
mBody->SetGravityScale(0.f);
mBody->SetUserData(this);
b2PolygonShape tBodyShape;
tBodyShape.SetAsBox(pWidth / 2.f / PIXELS_IN_METER, pHeight / 2.f / PIXELS_IN_METER);
b2FixtureDef tBodyFixtureDef;
tBodyFixtureDef.shape = &tBodyShape;
tBodyFixtureDef.friction = 0.4f;
tBodyFixtureDef.density = 10.0f;
tBodyFixtureDef.restitution = 0.1f;
mFixture = mBody->CreateFixture( &tBodyFixtureDef );
}
C::C()
{
}
/*virtual*/ void C::callPureVirtualFunction()
{
}