代码之家  ›  专栏  ›  技术社区  ›  Kaiyakha

重新分配期间的跟踪/断点陷阱

  •  1
  • Kaiyakha  · 技术社区  · 4 年前

    我有一个一年前写的图形代码,现在不起作用了(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 . 有人能看出我错在哪里吗?

    1 回复  |  直到 4 年前
        1
  •  1
  •   Nate Eldredge    4 年前

    add_vertex , gptr->size == 8 gptr->matrix 指向指向malloc'ed内存的8个指针数组。

    gptr->size++;
    

    现在 gptr->size == 9

        gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*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));
    

    自从 传给 realloc . 不好的。

    您可以迭代循环 gptr->size - 1 gptr->matrix[gptr->size - 1] = malloc(...) 分别地或者,为了有点懒惰并避免代码重复,您可以初始化 gptr->matrix[gptr->size - 1] = NULL gptr->size 时间,并依赖于方便的功能 realloc(NULL, sz) 相当于 malloc(sz) .