2014-06-07 42 views
0
#include <iostream> 
#include <cstring> 

using namespace std; 

const char* level1[23] = 
{ 
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 
"X                X", 
"X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  X", 
"X X K       X   D    X X", 
"X XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXXX X X", 
"X X X  X     X     XXXXX X X", 
"X X XXXXX X XXXXXXXXXXXXXX XXXXXXXX XXXXXXXXXXX  X X", 
"X X  X X  D  X X  X X  X XXXXX X", 
"X X XXXX X X XXXXXXXXXX X  X   X XXXX  X X", 
"X  X  X X E X XXXXXXXXX XXXXXXXX X XXXXX X X", 
"X XXXXXXXXXXXXXXXX D X XXK  X  X X X  KX X", 
"X X  X  X KX XXXXXX XXXXXX XXXXXXXX X X X XXXXXXDX", 
"X X X X X X X   XXX X   X X X D X X", 
"X X X X X X XXXXXXXXXXXXXXX XXXXXXXXXXXXXX X XXXXX X X", 
"X X X X X X X X    X   KX X  X X", 
"X X X X X X X X XXXXXXXXXXX X XXXXXXXXXXX X XXXXX X", 
"X X X X X X X X X  X KX X X   X  X X", 
"X  X X X X X  X X  XX X X  XXXXXXXXXXXXX X X", 
"X X X X X X X X X XXXXXXXX X X  X  X  X X", 
"X X X  X  X X X   X X X X  X   X X", 
"X X XXXXXXXXXXXXX X XXXXXXXX X X X XXXXXXXXXXXXXXXXXX X", 
"XS X               X", 
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 
}; 

// Player structure 
struct playerinfo 
{ 
    int x;  // X position 
    int y;  // Y position 
    int keys; // Number of keys the player has 
}; 

// Current game info structure 
struct gameinfo 
{ 
    char** board;  // The maze array 
    int maxx;   // Max size of the maze array X coordinate 
    int maxy;   // Max size of the maze array X coordinate 
    int level;   // The level of the maze 
    playerinfo player;  // Link to player data struct 
}; 

// Initializes the dynamic array that stores the maze 
char** initboard(gameinfo game) 
{ 
    char** matrix = new char*[game.maxx]; 

    for (int i=0; i<game.maxx; i++) 
     matrix[i] = new char[game.maxy]; 

    return matrix; 

} 

void delboard(gameinfo game) 
{ 
    for (int i=0;i<game.maxx;i++) 
     delete [] game.board[i]; 
    delete [] game.board; 
} 

int main() 
{ 
    gameinfo game; 

    game.maxx=65; 
    game.maxy=23; 

    game.board = initboard(game); 
    memcpy(game.board,level1,sizeof(level1)); 

    delboard(game); 
} 

核心转储填充之后删除动态二维数组时(核心转储)发生在的“delete [] game.board[i];”的第一步...当使用memcpy()线这只发生。我想要做的是将c-string常量的内容复制到动态二维数组中。问题是,游戏中会有多个可能不同大小的游戏。我最初尝试game.board[0] = "contents of line 0" ... game.board[23] = "contents of line 23",但这给了编译器警告。奇怪的是,这完美地在Windows下使用MinGW,但我需要这个也可以在Linux上使用。中止使用的memcpy

+3

你可能想问自己,当你调用它时,你实际上是'memcpy''吗?你正在对刚分配的整个行缓冲区指针进行爆破,然后试图“删除”一堆从未实际分配过的指针。更糟的是,你这样做*两次*,每次都泄漏整个动态行缓冲区。并且这被标记为** C ** ..为什么呢? – WhozCraig

+2

而且地球上没有机会“完美地运作”*任何地方*。你正在用静态表中的'const char * *'序列替换一系列动态行缓冲区指针,然后在这些指针上调用'delete []'。编译器后端无关紧要,你在做的是UB。 – WhozCraig

+0

这真的让我想起用C++编写C代码。通过使用一些C++容器来接受一些C++习惯用法,我保证你的生活会更容易。 – shuttle87

回答

1

这条线:

memcpy(game.board,level1,sizeof(level1)); 

是错误的,因为:

  1. 它覆盖的game.board的内容,这是被分配由level1内容持有的char*阵列。

  2. 你正在写内存,你没有分配。

你可以通过改变initboardlevel1内容复制到合适的存储位置,并删除上面的一行解决问题。

char** initboard(gameinfo game) 
{ 
    char** matrix = new char*[game.maxx]; 

    for (int i=0; i<game.maxx; i++) 
    { 
     matrix[i] = new char[game.maxy]; 

     // Copy the contents of `level1[i]` to `matrix[i]`. 
     strpcy(matrix[i], level1[i]); 
    } 

    return matrix; 
} 

更新(感谢@WhozCraig的目光敏锐)

您使用game.maxxgame.maxy值是颠倒的。您需要:

game.maxx=23; // Not 65; 
game.maxy=65 // Not 23; 

然后,你需要在initboard分配game.maxy+1字符。

 matrix[i] = new char[game.maxy+1]; 

否则,就不会有足够的空间来容纳终止空字符matrix[i]

+0

注意:OP的索引使用不正确,在调用此操作前需要解决。 'level1'数组是23个const指针对char,每个指向一个65 + 1个字符的行(包括终止符)。传递给它的'game'中的值是这样的,它将分配一个由65个char指针组成的数组,然后为每个指针分配一个char宽度为23的元素,通过复制一个65 + 1的长度字符串来调用UB 23个字符的空间,在过程中为每行调用UB。 – WhozCraig

+0

@WhozCraig感谢您注意到问题并让我知道。我已经更新了答案。 –

0

您通过不调用new来分配堆栈,因此不需要在最后实际删除该数组。当代码运行完毕时,它将被处理!您不能在堆栈上删除,或者您将从您无权访问的地址删除,因此中止。

+2

'level1'不在堆栈__上分配! –

1

char** board;更改为vector<string> board;。摆脱initboarddelboard,并在main()去:

game.board = vector<string>(begin(level1), end(level1)); 

您可能需要包括vectorstringiterator。您也可以删除maxxmaxy,并直接从board中读取它们。

See it working ..看到这一切是多么简单?

+0

我真的很喜欢这种方式,我需要更多地了解矢量以及将来如何使用它们。我能够在没有它们的情况下实现它,但它看起来对于任何未来的项目都是更好的方法。 – Disk0rd