0

I recently posted a question dealing with linker errors... Well for whatever reason those errors went away and is replaced with this. When I try to run my program, the window opens and it appears to run, however Visual Studio 2013 then presents me with the error:

Unhandled exception at 0x000FBA44 in Top Down Shooter.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0.

And then takes me to a xutility file with a breakpoint here:

 #if _ITERATOR_DEBUG_LEVEL == 2
            if (_Myproxy != _Parent_proxy)
                {   // change parentage
                _Lockit _Lock(_LOCK_DEBUG);
                _Orphan_me();
                _Mynextiter = _Parent_proxy->_Myfirstiter;
                _Parent_proxy->_Myfirstiter = this;
                _Myproxy = _Parent_proxy;
                }

The arrow is on the _Mynextiter line. Does anyone know what is happening? I was initially using iterators to help go through some lists that I had, but I commented them out yet I still get this error and I'm not sure why

Edit: Ok, So after going back through the stack of methods called, the last piece of code that was called that was mine was this:

ChunkManager::ChunkManager(b2World *w){
    AbstractChunk *chunk = generateChunk(0, 0);

    loadedChunks.push_back(*chunk);

    for (int i = 0; i < 64; i++){
        for (int p = 0; p < 64; p++){

            if (std::rand() > .7){
                AbstractBlock block(i, p, 0, w);
            }

        }
    }
}

Now I remember when I wrote this I thought it was strange because loadedChunks is an std::list... I have never used lists so I thought it was strange that the list would only accept a pointer to a pointer to an object where in the <> of the list it clearly takes an object... I think this might be the source of my problem but I don't know how to fix it

Second Edit: Here is the ChunkManager class so you can see the lists I have

#pragma once

#include <iostream>
#include<list>
#include<vector>
#include "AbstractChunk.h"

#ifndef CHUNKMANAGER_H
#define CHUNKMANAGER_H

class ChunkManager
{
public:
    ChunkManager();
    ChunkManager(b2World *world);
    ~ChunkManager();
    bool isChunkLoaded(int x, int y);
    bool isChunkGenerated(int x, int y);
    void loadChunksArround(int x, int y);
    AbstractChunk* loadChunk(int x, int y);
    int unloadChunk(int x, int y);
    std::list<AbstractBlock>* getLoadedBlocks();
private:
    b2World *world;
    std::list<AbstractChunk> loadedChunks;
    std::list<AbstractBlock> loadedBlocks;
    AbstractChunk* generateChunk(int x, int y);
};

#endif

AbstractChunk.cpp:

    #include "AbstractChunk.h"


    AbstractChunk::AbstractChunk()
    {
    }

    AbstractChunk::AbstractChunk(int x, int y){
        xpos = x;
        ypos = y;
    }

    int AbstractChunk::getXpos(){
        return xpos;
    }

    AbstractChunk::~AbstractChunk()
    {
    }

AbstractBlock.cpp:

#include "AbstractBlock.h"


AbstractBlock::AbstractBlock()
{
}

AbstractBlock::AbstractBlock(int x, int y, float roation, b2World *world){

}

sf::Sprite AbstractBlock::draw(){
    sf::Sprite sprite;
    return sprite;
}

void AbstractBlock::destroy(b2World *world){

}


AbstractBlock::~AbstractBlock()
{
}

ChunkManager.cpp:

#include "ChunkManager.h"


ChunkManager::ChunkManager(){

}

//Ignore this, working on it now
void ChunkManager::destroy(){
    for (int i = 0; i < loadedChunks.size; i++){
        loadedChunks.
    }
}

ChunkManager::ChunkManager(b2World *w){
    AbstractChunk* chunk = generateChunk(0, 0);

    loadedChunks.push_back(chunk);

    for (int i = 0; i < 64; i++){
        for (int p = 0; p < 64; p++){

            if (std::rand() > .7){
                AbstractBlock block(i, p, 0, w);
            }

        }
    }
}


std::list<AbstractBlock>* ChunkManager::getLoadedBlocks(){
    return &loadedBlocks;
}


ChunkManager::~ChunkManager()
{
}

AbstractChunk* ChunkManager::generateChunk(int x, int y){

    if (!isChunkGenerated(x,y)){
        AbstractChunk chunk(x, y);
        return &chunk;
    }
    else
        return nullptr;
}

bool ChunkManager::isChunkGenerated(int x, int y){
    return false;
}

AbstractChunk* ChunkManager::loadChunk(int x, int y){
    return nullptr;
}

void ChunkManager::loadChunksArround(int x, int y){

    int chunkX = std::floor(x / 16);
    int chunkY = std::floor(y / 16);

    for (int i = -1; i < 2; i++){
        for (int p = -1; p < 2; p++){
            loadChunk(i, p);
        }
    }

}
MagnusCaligo
  • 707
  • 2
  • 8
  • 28
  • That breakpoint is a red herring. We need the context higher up in the call stack. – Zeta Jul 02 '15 at 05:20
  • @Zeta What do you mean by that? Do you want the whole xutility file? – MagnusCaligo Jul 02 '15 at 05:21
  • Nope. But xutility should tell you the function that called this function and so on. Go up till you end up in your own code; or is the code you presented already your own code? – Zeta Jul 02 '15 at 05:23
  • @AnT Oh! I didn't realize I could do that... I went back to the last piece of code the I wrote myself and I found something interesting that I remember was weird when I wrote it but I forgot about it... ill add the edits to the main question – MagnusCaligo Jul 02 '15 at 05:27
  • You should know the following debugging features: set/remove breakpoints, step (into|out), next, continue, pause, print (values|frame information) and call stack frame navigation. That being said, without `AbstractChunk` and `ChunkManger` it's unlikely that we'll find the error. But the amount of pointers and hard-coded sizes (64) worries me. Also, you're aware that `std::rand` returns a non-negative integer, so the `std::rand() > .7` will be true in ~ 1/65536 calls. – Zeta Jul 02 '15 at 05:32
  • 1
    "...it was strange that the list would only accept a pointer to a pointer to an object " - That list isn't taking a pointer-to-pointer; it is taking a *dereferenced* pointer. And "...where in the <> of the list it clearly takes an object..." - maybe clear to you; we can't see that decl. The name `AbstractChunk` has a *strong* aroma that you're [*object-slicing*](http://stackoverflow.com/search?q=%5Bcpp%5D+object+slicing) somewhere, but without an [**MCVE**](http://stackoverflow.com/help/mcve) its hard to say. – WhozCraig Jul 02 '15 at 05:32
  • @WhozCraig: Probably some `T` with `T::T(U*)` defined. Undefined behaviour ho! – Zeta Jul 02 '15 at 05:33
  • @Zeta No I didn't realize that it did, I figured it was similar to java and lua and return a value between 0 and 1... ill fix that later, I want to finish this first – MagnusCaligo Jul 02 '15 at 05:38
  • @WhozCraig I added the ChunkManager class the question, if you want I can also add the AbstractBlack and AbstractChunk if that helps make it more clear... also I have no idea what object splicing is – MagnusCaligo Jul 02 '15 at 05:38
  • @MagnusCaligo: Are there default arguments in `AbstractChunk.h` for `AbstractChunk::AbstractChunk(int, int)`? – Zeta Jul 02 '15 at 05:41
  • OK. finally, `generateChunk` please. I'm truly curious why that is returning a *pointer*. Is it a static address returned? Fyi I think we're closer to finding the root problem than it may seem to you. – WhozCraig Jul 02 '15 at 05:41
  • @WhozCraig Its returning a pointer because (I havent implemented it yet) I want to make sure that the chunk isn't actually generated and that it isn't already loaded. If it is, I want the function to return a null pointer so that I can check later to see if its failed – MagnusCaligo Jul 02 '15 at 05:46
  • @MagnusCaligo that doesn't make much difference right now. But *how* it gets the pointer it returns makes a difference. Hopefully it isn't miles long; add it to your posted text. With any luck, it isn't returning dynamic-allocations of derivations of `AbstrackChunk`. if it is, you definitely have a slicing problem. If its returning dynamic-allocated *anything* you have an outright memory leak. – WhozCraig Jul 02 '15 at 05:48
  • `return &chunk;` is your problem. That returns an address of an automatic variable (one that ceases to exist the moment the function returns). upon return the address is invalid, and any dereference, or even eval, isn't allowed. In short, you're invoking *undefined behavior*. – WhozCraig Jul 02 '15 at 06:02
  • @WhozCraig Woah! I didn't even realize I was doing that! Thats a major error o_O I don't know what I was thinking lol must have been typing fast – MagnusCaligo Jul 02 '15 at 06:04
  • I would advise you find another way to communicate no-op besides a nullptr. Ex: `std::pair` where the `second` member indicates whether the `first` (the chunk) is relevant or valid is one such option. Regardless, heed 6502's advice. *Get a good book!*. – WhozCraig Jul 02 '15 at 06:06

1 Answers1

4

Your code denotes some confusion on very fundamental concepts like value and identity in C++. For example in

AbstractChunk *chunk = generateChunk(0, 0);

seems that generateChunk will allocate an object on the free store. Then however in:

loadedChunks.push_back(*chunk);

you are storing a copy of the allocated object in a container and the pointer is never used later (thus leaking the object).

Wildly guessing from the name, AbstractChunk is an abstract class with derived classes and the list should be an heterogeneous list of chunks of different types.

This is simply not possible in C++ (see the fundamental concepts of "slicing" and "copy semantic" of C++). You need to use a list of pointers to chunks instead.

Note that piling up a long stream of statements without understanding deeply how things works is a suicide strategy with C++. Even the fact that you assume that if you make a mistake the system will tell you so denotes you don't know how C++ works (see "undefined behavior" concept).

C++ cannot be learned by experimentation. You need to read a good book or two from cover to cover first.

There is no way to learn C++ except than by reading (and the smarter you are the worse the guessing approach will work... the reason is that in quite a few places the correct answer is not logical, but a consequence of an historic accident).

Community
  • 1
  • 1
6502
  • 112,025
  • 15
  • 165
  • 265
  • I figured something like this was happening, however I couldn't seem any other way to push back the chunk in the loadedChunks list... for some reason this was the only way I could get it in there and it confused me greatly... I'm not experienced in C++ – MagnusCaligo Jul 02 '15 at 05:44
  • 1
    @MagnusCaligo Then you should [get a book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Zeta Jul 02 '15 at 05:50
  • @6502 Yea I just figured that out for myself and it worked! I accidentally created a memory leak in my pc because I didn't remove the pointer, but ill fix it so it doesn't happen again – MagnusCaligo Jul 02 '15 at 05:54
  • @6502 Trust me, I want a book so bad because this language is difficult. I don't want to spend $60 to buy a book (especially when its difficult to decide which one to get) until I need it in college and there aren't any libraries in a 30 mile radius that have C++ books, so the only way for me to go is youtube videos and experimentation... that's how I learned Lua and Java – MagnusCaligo Jul 02 '15 at 05:57
  • @MagnusCaligo: keeping by experimenting unfortunately what will happen is that you will keep adding features and at a certain point the program will stop working. You will revert last changes and the program will keep behaving wrongly. You will blame the compiler, the operating system, the computer, the cosmic rays. This has happened to a jillion other C++ programmers... if you don't fix your approach to C++ now it will be a very sad experience. – 6502 Jul 02 '15 at 05:59
  • @6502 How is that possible? Does it affect how it builds or something? And I'm sorry but that isn't going to make me stop, because I want to learn and I will keep messing around because it's fun and it helps me better understand – MagnusCaligo Jul 02 '15 at 06:02
  • @MagnusCaligo: unfortunately you're right that most good C++ resources are not free. "Thinking in C++" is not bad however and is freely available. Unfortunately the web is also full of very bad introductions to C++. Remember to double-check the source before burning your neurons and remember that the price tag doesn't say it all... there are non-free bestsellers on C++ that are nice to read and memorize, but horribly wrong and full of conceptual mistakes. – 6502 Jul 02 '15 at 06:05
  • Hmmm..... well the program starts and works fine.... till I close it.... then I get the same error again.... Ill fix it tomorrow... goodnight :D – MagnusCaligo Jul 02 '15 at 06:14