我的代码使用两种结构,块和布局(它是任意数量的块的集合)。
struct block{
char type;
unsigned short int loc;
unsigned short int size[2];
};
struct layout{
unsigned short int no;
struct block *blocks;
short int **moves;
};
我正在使用此函数根据一组块快速初始化(并部分填充)结构布局:
struct layout init_layout(int block_no, struct block *blocks){
struct layout new_layout;
int i, j;
new_layout.no = (unsigned short int)block_no;
// the following two lines cause an memory corruption error
new_layout.blocks = (struct block *)malloc(block_no);
new_layout.moves = (short int **)malloc(block_no);
for(i = 0; i < block_no; i++){
new_layout.blocks[i] = blocks[i];
new_layout.moves[i] = (short int *)malloc(2);
for(j = 0; j < 2; j++)
new_layout.moves[i][j] = 0;
}
return new_layout;
}
到目前为止,我没有看到,它有什么问题。但是,当我调用这样的函数时
int main(int argc, char** argv){
// just some arbitrary values for 10 blocks
int size[2] = {2, 2};
struct block *blocks = (struct block *)malloc(10);
for(length = 0; length < 10; length++){
blocks[length] = init_block('R', 1, size);
}
struct layout puzzle;
puzzle = init_layout(10, blocks);
return 0;
}
我最终遇到内存损坏错误,正如init_layout()中的注释所标记的那样。 我的实施中会错过什么?
答案 0 :(得分:1)
当你为任何东西分配内存时,你需要仔细分析 - &#34; 我为什么分配内存?&#34;
下面,您错误地假设任意数字block_no
的强制将充分调整new_layout.blocks
和new_layout.moves
所需的内存大小 - 它赢了&# 39; T:
new_layout.blocks = (struct block *)malloc(block_no);
new_layout.moves = (short int **)malloc(block_no);
您为new_layout.blocks
分配的内容实际上是struct block *blocks;
的空间(指针到结构块),而您可以malloc (block_no * sizeof (struct block));
分配block_no
struct block的空间,最好根据你创建的内容进行分配(即数组的空间new_layout.blocks
(同样是指向结构块的指针 )需要block_no * sizeof *new_layout.blocks
字节的内存来保存block_no
类型的struct block
,例如:
new_layout.blocks = malloc(sizeof *new_layout.blocks * block_no);
new_layout.moves = malloc(sizeof *new_layout.moves * block_no);
(简单地解除引用您正在分配数组的对象,将准确地允许您使用sizeof
来获取数组的对象(元素)大小。(例如sizeof *new_layout.blocks
)您乘以您需要多少(例如sizeof *new_layout.blocks * block_no)
同样适用于:
new_layout.moves[i] = malloc(**new_layout.moves * 2);
(注意:这里你要分配2个短裤,所以你需要两次取消引用指针到指针到短路两次以分配给{ {1}})
另请参阅: Do I cast the result of malloc?以获得详尽的解释。
答案 1 :(得分:1)
首先,这个
new_layout.blocks = (struct block *)malloc(block_no);
应该是
new_layout.blocks = malloc(block_no * sizeof *new_layout.blocks);
对于moves
,这有点复杂。
假设short int **moves;
应该引用一定数量的int[2]
,则声明不是最佳的,应该更好:
short int (*moves)[2]; /* Define a pointer to
an array with two elements of type short int. */
然后分配应该是这样的:
new_layout.moves = malloc(block_no * sizeof *new_layout.moves);
最后初始化是这样的:
for(i = 0; i < block_no; i++){
new_layout.blocks[i] = blocks[i];
for(j = 0; j < sizeof new_layout.moves[0]/sizeof new_layout.moves[0][0]; j++)
new_layout.moves[i][j] = 0;
}
你可能已经注意到了:
2
仅出现一次。: - )