简体   繁体   English

从C ++中的结构中包含的指针数组动态分配和访问内存

[英]Dynamically allocating and accessing memory from an array of pointers contained within a struct in C++

Sorry for the super-lengthy title, but... it DID say to be specific... anyway! 抱歉,您的标题太长了,但是...还是要说具体... I'm making an algorithm designed to solve sliding-block puzzle games. 我正在设计一种算法,用于解决滑块益智游戏。 To do this, I need to store all possible variations of a game board within nodes. 为此,我需要将游戏板的所有可能版本存储在节点中。 Each game board state is stored within a node that also contains pointers to its parent (ie the state right before its present state) and all of its children (all possible states available from its present state). 每个游戏板状态都存储在一个节点中,该节点还包含指向其父级(即,其当前状态之前的状态)及其所有子级(从其当前状态可用的所有可能状态)的指针。 Here's the node struct I've built: 这是我构建的节点结构:

struct node
{
    //Attributes
    char gameBoardState[5][4];
    node* parent;
    int numChildren;
    node* childArray[10];

    //Constructor
    node(char pGameState[][4], node* pParent = NULL, int pNumChildren = 0, node* pChildArray[] = NULL)
    {
        //For each row i
        for (int i = 0; i < 5; i++)
        {
            //For each column j
            for (int j = 0; j < 4; j++)
            {
                //Set each block equal to this
                gameBoardState[i][j] = pGameState[i][j];
            }
        }
    }
};

My issue is in this section of code here, designed purely to test whether or not I could access data properly and such (I've designed the functions that actually move the pieces around, but not yet implemented them): 我的问题在此处的这段代码中,其目的纯粹是为了测试我是否可以正确访问数据(例如,我设计了实际上可以移动但尚未实现的功能):

//Sample board state
char sampleBoard[5][4];
char sampleBoard2[5][4];
//Sample character
char sample = 'a';
char sample2 = 'z';
//Initialize the sample board
for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 4; j++)
    {
        sampleBoard[i][j] = sample;
        sampleBoard2[i][j] = sample2;
        sample++;
        sample2--;
    }
}

//Test
cout << "\n\nERROR BEGINS\n\n";

//Create first node
node top = node(sampleBoard);
//Create a child node
top.childArray[top.numChildren] = new node(sampleBoard2, &top);

//Test
cout << "\n\nERROR ENDS\n\n";

For whatever reason, the lines right between the ERROR comments generate a memory access error. 无论出于何种原因,在ERROR注释之间的右行都会产生内存访问错误。 I've looked at all kinds of C++ tutorials regarding pointers, arrays, structs, and combinations thereof. 我看过各种有关指针,数组,结构及其组合的C ++教程。 I've also tried omitting the "&top" in the "new node" call; 我还尝试在“新节点”调用中省略“&top”; didn't help. 没有帮助。 I'm just not seeing how my code is generating this error in memory access. 我只是看不到我的代码如何在内存访问中生成此错误。 I also looked through over a dozen answers here, though none of them with solutions that seemed applicable to my situation. 我在这里也浏览了十几个答案,尽管没有一个答案适合我的情况。 I get the feeling I'm missing something fairly obvious. 我感到自己缺少明显的东西。 Any help, even if its just redirection to a valid answer that I've somehow overlooked? 有什么帮助,即使只是重定向到我以某种方式忽略的有效答案? Thanks in advance! 提前致谢!

The issue is actually quite simple, you never initialized numChildren . 问题实际上很简单,您从未初始化numChildren

Therefore, attempting to say top.childArray[top.numChildren] ... will likely result in numChildren evaluating to some ridiculous (possibly negative) number. 因此,尝试说top.childArray[top.numChildren] ...可能会导致numChildren评估为一些荒谬(可能为负)的数字。

The bigger issue here is that your code is poorly designed. 这里更大的问题是您的代码设计不良。 It's very C-like in that you're using a lot of raw pointers and arrays where the sizing information is separate. 它非常类似于C,因为您使用了许多原始指针和数组,其中大小信息分开。 Also, the onus of tracking the lifetime of these pointers is on you instead of happening automatically. 同样,跟踪这些指针的生存期的责任在于您,而不是自动发生。

I suggest you look into refactoring your code with std::vector and std::string , which provide indexing operations as well as .size() , and your code will become much safer. 我建议您考虑使用std::vectorstd::string重构代码,它们提供索引操作以及.size() ,您的代码将变得更加安全。

You could additionally encapsulate char gameBoardState[5][4]; 您还可以封装char gameBoardState[5][4]; into a class GameBoard that can be arbitrarily sized at construction (using vector as before). 放入一个可以在构造时任意设置大小的class GameBoard (与以前一样使用vector )。 This has the additional benefit of you not needing to change code all over the place should you decide to test with different game boards. 这样做的另一个好处是,如果您决定使用不同的游戏板进行测试,则无需在各处更改代码。

In

top.childArray[top.numChildren] = new node(sampleBoard2, &top);

numChildren was never initialized. numChildren从未初始化。 This means it has some garbage value. 这意味着它具有一些垃圾值。 More than likely it is a value that is outside [0, 9] so you are accessing memory you do not own which is UB and will/can cause memory access errors. 很有可能它是[0,9]以外的值,因此您正在访问不属于UB的内存,它将/可能导致内存访问错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM