Trace/breakpoint 重新分配时陷入陷阱
Trace/breakpoint trap during reallocation
我有一个一年前写的图表代码,现在不能用了(AFAIR 它能用)。该图是用分别与对角线对称的方阵实现的。我省略了很多代码以使其尽可能清晰,这仍然足以使错误持续存在。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct
{
int **matrix;
unsigned size;
} graph;
void init(graph *gptr, int *matrix[], unsigned size)
{
gptr->size = size;
gptr->matrix = malloc(gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
gptr->matrix[i] = malloc(gptr->size * sizeof(**gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
for (unsigned j = 0; j <= i; j++)
gptr->matrix[i][j] = gptr->matrix[j][i] = matrix[i][j];
}
void add_vertex(graph *gptr, unsigned vertex)
{
for (unsigned i = 1; i < gptr->size; i++)
if (gptr->matrix[i][0] == vertex) return;
gptr->size++;
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
gptr->matrix[gptr->size - 1][0] = gptr->matrix[0][gptr->size - 1] = vertex;
for (unsigned i = 1; i < gptr->size; i++)
gptr->matrix[gptr->size - 1][i] = gptr->matrix[i][gptr->size - 1] = -1;
}
#define EDGES 7
#define RANDOM(min, max) min + rand() / ((RAND_MAX - 1) / (max - min))
#define MIN -1
#define MAX 9
int **getMatrix(unsigned size)
{
int **matrix = malloc(size * sizeof(*matrix));
for (unsigned i = 0; i < size; i++)
{
matrix[i] = malloc((i + 1) * sizeof(**matrix));
matrix[i][0] = i;
}
for (unsigned i = 1; i < size; i++)
{
for (unsigned j = 1; j < i; j++)
do
matrix[i][j] = RANDOM(MIN, MAX);
while (!matrix[i][j]);
matrix[i][i] = rand() % 2 - 1;
}
return matrix;
}
int main(void)
{
int **matrix = getMatrix(EDGES + 1);
graph x;
init(&x, matrix, EDGES + 1);
add_vertex(&x, EDGES + 1);
}
在 gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
处,程序因异常 Trace/breakpoint trap
暂停。我用谷歌搜索了一段时间,对我来说很可能是我的重新分配出了问题,但我不知道出了什么问题。此外,它在 clang
甚至在线 gcc 7.4
上运行良好,而在我的 gcc 8.1
上却无法成功。谁能看出我错在哪里?
在 add_vertex
的第一个条目上,gptr->size == 8
和 gptr->matrix
指向一个由 8 个指向 malloc 内存的指针组成的数组。
gptr->size++;
现在gptr->size == 9
.
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
现在gptr->matrix
指向一个9指针数组。 gptr->matrix[0] .. gptr->matrix[7]
是之前有效的 malloc'ed 指针,gptr->matrix[8]
包含未初始化的垃圾。
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
从gptr->size == 9
开始,迭代9次,在第9次迭代时,垃圾指针gptr->matrix[8]
被传递给realloc
。不好。
您可以将循环迭代 gptr->size - 1
次,然后单独初始化 gptr->matrix[gptr->size - 1] = malloc(...)
。或者为了有点懒惰并避免代码重复,你可以在这个循环之前初始化 gptr->matrix[gptr->size - 1] = NULL
,让它迭代 gptr->size
次,并依赖 realloc(NULL, sz)
等同于 malloc(sz)
.
我有一个一年前写的图表代码,现在不能用了(AFAIR 它能用)。该图是用分别与对角线对称的方阵实现的。我省略了很多代码以使其尽可能清晰,这仍然足以使错误持续存在。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct
{
int **matrix;
unsigned size;
} graph;
void init(graph *gptr, int *matrix[], unsigned size)
{
gptr->size = size;
gptr->matrix = malloc(gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
gptr->matrix[i] = malloc(gptr->size * sizeof(**gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
for (unsigned j = 0; j <= i; j++)
gptr->matrix[i][j] = gptr->matrix[j][i] = matrix[i][j];
}
void add_vertex(graph *gptr, unsigned vertex)
{
for (unsigned i = 1; i < gptr->size; i++)
if (gptr->matrix[i][0] == vertex) return;
gptr->size++;
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
gptr->matrix[gptr->size - 1][0] = gptr->matrix[0][gptr->size - 1] = vertex;
for (unsigned i = 1; i < gptr->size; i++)
gptr->matrix[gptr->size - 1][i] = gptr->matrix[i][gptr->size - 1] = -1;
}
#define EDGES 7
#define RANDOM(min, max) min + rand() / ((RAND_MAX - 1) / (max - min))
#define MIN -1
#define MAX 9
int **getMatrix(unsigned size)
{
int **matrix = malloc(size * sizeof(*matrix));
for (unsigned i = 0; i < size; i++)
{
matrix[i] = malloc((i + 1) * sizeof(**matrix));
matrix[i][0] = i;
}
for (unsigned i = 1; i < size; i++)
{
for (unsigned j = 1; j < i; j++)
do
matrix[i][j] = RANDOM(MIN, MAX);
while (!matrix[i][j]);
matrix[i][i] = rand() % 2 - 1;
}
return matrix;
}
int main(void)
{
int **matrix = getMatrix(EDGES + 1);
graph x;
init(&x, matrix, EDGES + 1);
add_vertex(&x, EDGES + 1);
}
在 gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
处,程序因异常 Trace/breakpoint trap
暂停。我用谷歌搜索了一段时间,对我来说很可能是我的重新分配出了问题,但我不知道出了什么问题。此外,它在 clang
甚至在线 gcc 7.4
上运行良好,而在我的 gcc 8.1
上却无法成功。谁能看出我错在哪里?
在 add_vertex
的第一个条目上,gptr->size == 8
和 gptr->matrix
指向一个由 8 个指向 malloc 内存的指针组成的数组。
gptr->size++;
现在gptr->size == 9
.
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
现在gptr->matrix
指向一个9指针数组。 gptr->matrix[0] .. gptr->matrix[7]
是之前有效的 malloc'ed 指针,gptr->matrix[8]
包含未初始化的垃圾。
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
从gptr->size == 9
开始,迭代9次,在第9次迭代时,垃圾指针gptr->matrix[8]
被传递给realloc
。不好。
您可以将循环迭代 gptr->size - 1
次,然后单独初始化 gptr->matrix[gptr->size - 1] = malloc(...)
。或者为了有点懒惰并避免代码重复,你可以在这个循环之前初始化 gptr->matrix[gptr->size - 1] = NULL
,让它迭代 gptr->size
次,并依赖 realloc(NULL, sz)
等同于 malloc(sz)
.