简体   繁体   中英

ImageMagick++ 7 causes non deterministic behavior in my C++ program

If executing library code results in non-deterministic behavior from some unrelated code which otherwise behaves deterministically and as expected, is it safe to assume it is a problem with the library?

I have a C++ program which does stuff. (It interprets a string as an occupancy grid and, given an initial and final grid index, it computes and prints the shortest path using the A* search algorithm.)

By itself it works great. But when I run some code from the Magick++ 7 library, before my code, I get unexpected and non deterministic behavior. This doesn't occur if I run the library code afterward.

Is it possible there is something wrong with my code, or can I assume it is a problem with the library?

(The reason I was playing with Magick++ is because I'd like to initialize my occupancy grid using an image, and write the computed path to an image as well.)

The specific failure mode is, a few spaces in the last row of the grid may or may not appear to occupied when printing the final path. It seems completely random. The problem goes away if I run the Magick++ code after doing my path finding.

Here is my code:

example.cpp:

#include <stdio.h>
#include <Magick++.h>
#include "astar.h"
#include <iostream>

#define MAX_PATH_SIZE 255
#define MAX_RGB 65535

using std::cout;
using std::endl;

int main(int argc, char** argv)
{
    // running this causes undefined behavoir, apparently
    // Magick::InitializeMagick(*argv); 
    
    // Magick::Image image;
    
    // image.read("img/32x32-1.png");
    // cout << image.columns() << endl;
    // cout << image.rows() << endl;
    // Magick::Color pixel_sample;
    // pixel_sample = image.pixelColor(0,0);
    // Magick::Quantum red = pixel_sample.quantumRed();
    // Magick::Quantum green = pixel_sample.quantumGreen();
    // Magick::Quantum blue = pixel_sample.quantumBlue();
    // Magick::Quantum alpha = pixel_sample.quantumAlpha();
    // cout << red << endl;
    // cout << green << endl;
    // cout << blue << endl;
    // cout << alpha << endl;

    // image.pixelColor(0,0, "red");
    // image.write("out.png");
    
    int result = 0;   

char grid_string[2000] = "\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . # # . . . . . . . . . . . . . . . . .\n\
. . . . . # . . . . . . . . . . . . . . . . .\n\
. . # # . # . . . . . . . . . . . . . . . . .\n\
. . . # # # . . . # . . . . . . . . . . . . .\n\
. . . . . # . . . # . . . . . . . . . . . . .\n\
. . . . . # # # # # . . . . . . . . . . . . .\n\
. . . . . # # . . . . . . . . . . . . . . . .\n\
. . . . . # . . . . . . . . . . . . . . . . .\n\
. . . . # # . . . . . . . . . . . . . . . . .\n\
. . . . # . . . . . . . . . . . . . . . . . .\n\
. . . # # . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .\n\
. . . . . . . . . . . . . . . . . . . . . . .";

    Grid grid;
    char err = grid_init_str(grid_string, &grid);
    if (err) {
        printf("err: %d\n", err);
        result = err;
        free(grid.obstacles);
        return result;
    }
    // grid_print(&grid);
    // grid_print_mark(&grid, 408);
    
    unsigned int path[MAX_PATH_SIZE]; // [0, 65535]
    unsigned char path_size = 0; // [0, 255]
    err = grid_find_path(&grid, 0, 408, path, &path_size, MAX_PATH_SIZE);
    switch (err) {
    case 0:
        grid_print_path(&grid, path, path_size);
        for (unsigned char i = 0; i < path_size; ++i) {
            printf("%u ", path[i]);
        }
        printf("\n");
        break;
    case 1:
        result = 1;
        printf("Path not found\n");        
        break;
    case -1:
        printf("Path exceeded max path size\n");
        grid_print_path(&grid, path, path_size);
        for (unsigned char i = 0; i < path_size; ++i) {
            printf("%u ", path[i]);
        }
        printf("\n");
        break;
    case -2:
        printf("Invalid Destination\n");
        break;
    case -3:
        printf("Invalid start\n");
        break;
    }
    
    free(grid.obstacles);
    return result;
}

astar.h:

#ifndef GUARD_astar_h
#define GUARD_astar_h

#include <stdio.h>
#include <stdint.h> // not using yet
#include <string.h>
#include <stdlib.h>
#include <math.h> // defines INFINITY and -INFINITY macros

typedef char Err;

typedef struct Grid {
    unsigned char* obstacles; // bit array
    unsigned char cols; // [0, 255]
    unsigned char rows; // [0, 255]
} Grid;

unsigned grid_distance(const Grid* grid, const unsigned int i, const unsigned int j);
Err grid_find_path(const Grid* grid, const unsigned int start, const unsigned int dest, unsigned int* path, unsigned char* path_size, const unsigned char max_path_size);
unsigned char grid_obstacle_at(const Grid* grid, size_t idx);
void grid_print(const Grid* grid);
void grid_print_mark(const Grid* grid, const size_t marked);
void grid_print_path(const Grid* grid, const unsigned int* path, const unsigned char path_size);
Err grid_init_str(char* s, Grid* grid);
void grid_idx_to_cartesian(const Grid* grid, const unsigned int i, int* x, int* y);

#endif

astar.cpp:

#include "astar.h"

void printBits(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;
    
    for (i = size-1; i >= 0; i--) {
        for (j = 7; j >= 0; j--) {
            byte = (b[i] >> j) & 1;
            printf("%u", byte);
        }
    }
    puts("");
}

unsigned char grid_obstacle_at(const Grid* grid, size_t idx)
{
    const unsigned char bit_idx = (idx % 8);
    const size_t byte_idx = idx / 8;
    return (grid->obstacles[byte_idx] & (1 << bit_idx)) >> bit_idx;
}

void grid_print(const Grid* grid)
{    
    for (size_t i = 0; i < (grid->cols * grid->rows); ++i) {     
        printf("%c ", grid_obstacle_at(grid, i) ? '#' : '.');
        if ((i+1) % grid->cols == 0) {
            printf("\n");
        }
    }
}

void grid_print_mark(const Grid* grid, const size_t marked)
{    
    for (size_t i = 0; i < (grid->cols * grid->rows); ++i) {
        if (i == marked) {
            printf("@ ");
        }
        else {
            printf("%c ", grid_obstacle_at(grid, i) ? '#' : '.');
        }
        if ((i+1) % grid->cols == 0) {
            printf("\n");
        }
    }
}

void grid_print_path(const Grid* grid, const unsigned int* path, const unsigned char path_size)
{
    for (size_t i = 0; i < (grid->cols * grid->rows); ++i) {
        bool in_path = false;
        for (size_t j = 0; j < path_size; ++j) {
            if (path[j] == i) {
                in_path = true;
                break;
            }
        }
        
        if (in_path) {
            printf("@ ");
        }
        else {
            printf("%c ", grid_obstacle_at(grid, i) ? '#' : '.');
        }
        if ((i+1) % grid->cols == 0) {
            printf("\n");
        }
    }
}

Err grid_init_str(char* s, Grid* grid)
{
    grid->cols = 0;
    grid->rows = 0;
    char end_row_found = 0;
    for (size_t i = 0; i < strlen(s); ++i) {
        if (s[i] == '\n') {
            end_row_found = 1;
            grid->rows++;
        }
        if (!end_row_found) {
            if (s[i] != ' ') {
                grid->cols++;
            }
        }
    }
    grid->rows++;
    size_t grid_size = (grid->cols * grid->rows * sizeof(char)) / 8;
    grid->obstacles = (unsigned char*) malloc(grid_size);
    for (size_t i = 0; i < grid_size; ++i) {
        grid->obstacles[i] = 0;
    }
    
    char* delim = "\n";    
    char* row = strtok(s, delim);

    int j = 0;  // byte index
    char k = 0; // bit index
    while (row != NULL) {
        for (size_t i = 0; i < strlen(row); ++i) {
            switch (row[i]) {
            case ' ':
                continue;
                break;
            case '.':
                if (++k == 8) {
                    k = 0;
                    ++j;
                }
                break;
            case '#':
                grid->obstacles[j] = grid->obstacles[j] | (1<<k);
                if (++k == 8) {
                    k = 0;
                    ++j;
                }
                break;
            default:
                printf("Unexpected char: %c\n", row[i]);
                return 1;
            }
        }
        
        row = strtok(NULL, delim);
    }

    return 0;
}

typedef struct Node {
    unsigned int grid_idx;
    Node* parent;
    unsigned gCost;
    unsigned hCost;
    bool operator<(Node o) {
        return (gCost + hCost) < (o.gCost + o.hCost);
    }
    bool operator>(Node o) {
        return (gCost + hCost) > (o.gCost + o.hCost);
    }
} Node;

void grid_idx_to_cartesian(const Grid* grid, const unsigned int i, int* x, int* y)
{
    *x = i % grid->cols;
    *y = i / grid->cols;    
}

unsigned grid_distance(const Grid* grid, const unsigned int i, const unsigned int j)
{
    int ix;
    int iy;
    grid_idx_to_cartesian(grid, i, &ix, &iy);
    int jx;
    int jy;
    grid_idx_to_cartesian(grid, j, &jx, &jy);

    return round(10 * sqrt(pow((float)abs(jy - iy), 2) + pow((float)abs(jx - ix), 2)));    
}

int pq_parent(int i)
{
    return (i - 1) / 2;
}

int pq_left_child(int i)
{
    return (2 * i) + 1;
}

int pq_right_child(int i)
{
    return (2 * i) + 2;
}

void pq_shift_down(Node* pq, const size_t size, const unsigned int i)
{
    unsigned int minIndex = i;
    unsigned int l = pq_left_child(i);
    
    if (l < size && pq[l] < pq[minIndex]) {
        minIndex = l;
    }

    unsigned int r = pq_right_child(i);

    if (r < size && pq[r] < pq[minIndex]) {
        minIndex = r;
    }

    if (i != minIndex) {
        Node temp = pq[i];
        pq[i] = pq[minIndex];
        pq[minIndex] = temp;

        pq_shift_down(pq, size, minIndex);
    }
}

void node_copy(Node* orig, Node* cpy)
{
    cpy->grid_idx = orig->grid_idx;
    cpy->parent = orig->parent;
    cpy->gCost = orig->gCost;
    cpy->hCost = orig->hCost;
}

void pq_dequeue(Node* pq, size_t* size, Node* result)
{
    node_copy(pq, result);    
    pq[0] = pq[(*size)-1];
    (*size)--;
    pq_shift_down(pq, *size, 0);
}

void pq_shift_up(Node* pq, int i)
{
    while (i > 0 && pq[pq_parent(i)] > pq[i]) {
        int parent_i = pq_parent(i);
        Node temp = pq[i];
        pq[i] = pq[parent_i];
        pq[parent_i] = temp;

        i = parent_i;
    }
}

void node_print(Node* node)
{
    printf("[gC:%u gI:%u]", node->gCost, node->grid_idx);
}

void pq_print(Node* pq, size_t size)
{
    printf("pq: ");
    for (size_t i = 0; i < size; ++i) {
        node_print(pq+i);
    }
    printf("\n");
}

Err grid_find_path(const Grid* grid, const unsigned int start, const unsigned int dest, unsigned int* path, unsigned char* path_size, const unsigned char max_path_size)
{
    if (grid_obstacle_at(grid, start)) {
        return -2;
    }
    if (grid_obstacle_at(grid, dest)) {
        return -3;
    }
    // 5 6 7
    // 4 X 0
    // 3 2 1
    const int neighbors[8] = {1, grid->cols+1, grid->cols, grid->cols-1, -1, 0-grid->cols-1, 0-grid->cols, 0-grid->cols+1};

    const size_t pq_max_size = 100000; // EXAMINE THIS
    const size_t explored_max_size = pq_max_size; // AND THIS!

    Node pq[pq_max_size];
    pq[0].grid_idx = dest;
    pq[0].parent = NULL;
    pq[0].gCost = 0;
    pq[0].hCost = grid_distance(grid, dest, start);
    size_t pq_size = 1;
    
    Node explored[explored_max_size];
    size_t explored_size = 0;

    while (pq_size != 0) {
        pq_dequeue(pq, &pq_size, explored+explored_size);
        explored_size++;
        
        for (char i = 0; i < 8; ++i) {
            if (explored[explored_size-1].grid_idx < grid->cols && i >= 5) continue; // first row
            if (explored[explored_size-1].grid_idx % grid->cols == 0 && i >= 3 && i <= 5) continue; // first column
            if (explored[explored_size-1].grid_idx % grid->cols == grid->rows - 1 && (i <= 1 || i == 7)) continue; // last column
            if (explored[explored_size-1].grid_idx / grid->cols == grid->rows - 1 && (i <= 3 && i >= 1)) continue; // last row
        
            size_t neighbor_idx = explored[explored_size-1].grid_idx + neighbors[i];            
            if (grid_obstacle_at(grid, neighbor_idx)) continue;            

            if (neighbor_idx == start) { // this isn't necessarily the shortest, but good enough                
                path[0] = neighbor_idx;                
                (*path_size)++;
                Node* node_ptr = explored+(explored_size-1);
                for (int i = 1; node_ptr != NULL && *path_size < max_path_size; ++i) {
                    path[i] = node_ptr->grid_idx;                    
                    node_ptr = node_ptr->parent;
                    (*path_size)++;
                    if (*path_size == max_path_size && node_ptr != NULL) {
                        return -1;
                    }
                }                

                return 0;
            }

            // ask whether the neighbor_idx exists in the pq already
            bool in_pq = false;
            size_t pq_idx = 0;
            for (size_t i = 0; i < pq_size; ++i) {
                if (pq[i].grid_idx == neighbor_idx) {
                    in_pq = true;
                    pq_idx = i;
                    break;
                }
            }                        
            // If so, the gCost and parent may need to be updated to reflect a lower cost path
            if (in_pq) { // when switching to using fCost, this needs to be updated
                unsigned new_gCost = explored[explored_size-1].gCost + grid_distance(grid, explored[explored_size-1].grid_idx, neighbor_idx);
                if (new_gCost < pq[pq_idx].gCost) {
                    pq[pq_idx].gCost = new_gCost;
                    pq[pq_idx].parent = explored+(explored_size-1);
                    /* printf("modifying parent => &pq[pq_idx]: %x, &explored[explored_size-1]: %x\n", &(pq[pq_idx]), &explored[explored_size-1]); */                    
                    pq_shift_up(pq, pq_idx);                    
                }
            }
            else { // otherwise, add a new node to the queue as below
                pq[pq_size].grid_idx = neighbor_idx;
                pq[pq_size].parent = explored+(explored_size-1);
                /* printf("adding parent => &pq[pq_size]: %x, &explored[explored_size-1]: %x\n", &(pq[pq_size]), &explored[explored_size-1]); */
                pq[pq_size].gCost = explored[explored_size-1].gCost + grid_distance(grid, explored[explored_size-1].grid_idx, neighbor_idx);
                pq[pq_size].hCost = grid_distance(grid, neighbor_idx, start);
                pq_shift_up(pq, pq_size);
                ++pq_size;
            }
        }
    }
    
    return 1;
}

compiled like so:

g++ -lstdc++ -std=c++11 `Magick++-config --cxxflags --cppflags` -Wall -Wextra example.cpp astar.cpp -o example `Magick++-config --ldflags --libs`

program output:

@ @ @ @ @ @ . . . . . . . . . . . . . . . . . 
. . . . # # @ . . . . . . . . . . . . . . . . 
. . . . . # . @ . . . . . . . . . . . . . . . 
. . # # . # . . @ @ . . . . . . . . . . . . . 
. . . # # # . . . # @ . . . . . . . . . . . . 
. . . . . # . . . # @ . . . . . . . . . . . . 
. . . . . # # # # # @ . . . . . . . . . . . . 
. . . . . # # . . . @ . . . . . . . . . . . . 
. . . . . # . . . . @ . . . . . . . . . . . . 
. . . . # # . . . . @ . . . . . . . . . . . . 
. . . . # . . . . . @ . . . . . . . . . . . . 
. . . # # . . . . . . @ . . . . . . . . . . . 
. . . . . . . . . . . . @ . . . . . . . . . . 
. . . . . . . . . . . . . @ . . . . . . . . . 
. . . . . . . . . . . . . . @ . . . . . . . . 
. . . . . . . . . . . . . . . @ . . . . . . . 
. . . . . . . . . . . . . . . . @ . . . . . . 
. . . . . . . . . . . . . . . . . @ . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
0 1 2 3 4 5 29 53 77 78 102 125 148 171 194 217 240 264 288 312 336 360 384 408

The #'s represent occupied spaces, @'s represent a path through. If I uncomment the code at the top of main in example.cpp, I get non deterministic behavior:

duncanbritt@Duncans-MacBook-Pro maze-solver-c % ./example
32
32
65535
65535
65535
65535
@ @ @ @ @ @ . . . . . . . . . . . . . . . . . 
. . . . # # @ . . . . . . . . . . . . . . . . 
. . . . . # . @ . . . . . . . . . . . . . . . 
. . # # . # . . @ @ . . . . . . . . . . . . . 
. . . # # # . . . # @ . . . . . . . . . . . . 
. . . . . # . . . # @ . . . . . . . . . . . . 
. . . . . # # # # # @ . . . . . . . . . . . . 
. . . . . # # . . . @ . . . . . . . . . . . . 
. . . . . # . . . . @ . . . . . . . . . . . . 
. . . . # # . . . . @ . . . . . . . . . . . . 
. . . . # . . . . . @ . . . . . . . . . . . . 
. . . # # . . . . . . @ . . . . . . . . . . . 
. . . . . . . . . . . . @ . . . . . . . . . . 
. . . . . . . . . . . . . @ . . . . . . . . . 
. . . . . . . . . . . . . . @ . . . . . . . . 
. . . . . . . . . . . . . . . @ . . . . . . . 
. . . . . . . . . . . . . . . . @ . . . . . . 
. . . . . . . . . . . . . . . . . @ . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . # # # # # # # 
0 1 2 3 4 5 29 53 77 78 102 125 148 171 194 217 240 264 288 312 336 360 384 408 
duncanbritt@Duncans-MacBook-Pro maze-solver-c % ./example
32
32
65535
65535
65535
65535
@ @ @ @ @ @ . . . . . . . . . . . . . . . . . 
. . . . # # @ . . . . . . . . . . . . . . . . 
. . . . . # . @ . . . . . . . . . . . . . . . 
. . # # . # . . @ @ . . . . . . . . . . . . . 
. . . # # # . . . # @ . . . . . . . . . . . . 
. . . . . # . . . # @ . . . . . . . . . . . . 
. . . . . # # # # # @ . . . . . . . . . . . . 
. . . . . # # . . . @ . . . . . . . . . . . . 
. . . . . # . . . . @ . . . . . . . . . . . . 
. . . . # # . . . . @ . . . . . . . . . . . . 
. . . . # . . . . . @ . . . . . . . . . . . . 
. . . # # . . . . . . @ . . . . . . . . . . . 
. . . . . . . . . . . . @ . . . . . . . . . . 
. . . . . . . . . . . . . @ . . . . . . . . . 
. . . . . . . . . . . . . . @ . . . . . . . . 
. . . . . . . . . . . . . . . @ . . . . . . . 
. . . . . . . . . . . . . . . . @ . . . . . . 
. . . . . . . . . . . . . . . . . @ . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . # # . 
0 1 2 3 4 5 29 53 77 78 102 125 148 171 194 217 240 264 288 312 336 360 384 408 
duncanbritt@Duncans-MacBook-Pro maze-solver-c % ./example
32
32
65535
65535
65535
65535
@ @ @ @ @ @ . . . . . . . . . . . . . . . . . 
. . . . # # @ . . . . . . . . . . . . . . . . 
. . . . . # . @ . . . . . . . . . . . . . . . 
. . # # . # . . @ @ . . . . . . . . . . . . . 
. . . # # # . . . # @ . . . . . . . . . . . . 
. . . . . # . . . # @ . . . . . . . . . . . . 
. . . . . # # # # # @ . . . . . . . . . . . . 
. . . . . # # . . . @ . . . . . . . . . . . . 
. . . . . # . . . . @ . . . . . . . . . . . . 
. . . . # # . . . . @ . . . . . . . . . . . . 
. . . . # . . . . . @ . . . . . . . . . . . . 
. . . # # . . . . . . @ . . . . . . . . . . . 
. . . . . . . . . . . . @ . . . . . . . . . . 
. . . . . . . . . . . . . @ . . . . . . . . . 
. . . . . . . . . . . . . . @ . . . . . . . . 
. . . . . . . . . . . . . . . @ . . . . . . . 
. . . . . . . . . . . . . . . . @ . . . . . . 
. . . . . . . . . . . . . . . . . @ . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
0 1 2 3 4 5 29 53 77 78 102 125 148 171 194 217 240 264 288 312 336 360 384 408 
duncanbritt@Duncans-MacBook-Pro maze-solver-c % ./example
32
32
65535
65535
65535
65535
@ @ @ @ @ @ . . . . . . . . . . . . . . . . . 
. . . . # # @ . . . . . . . . . . . . . . . . 
. . . . . # . @ . . . . . . . . . . . . . . . 
. . # # . # . . @ @ . . . . . . . . . . . . . 
. . . # # # . . . # @ . . . . . . . . . . . . 
. . . . . # . . . # @ . . . . . . . . . . . . 
. . . . . # # # # # @ . . . . . . . . . . . . 
. . . . . # # . . . @ . . . . . . . . . . . . 
. . . . . # . . . . @ . . . . . . . . . . . . 
. . . . # # . . . . @ . . . . . . . . . . . . 
. . . . # . . . . . @ . . . . . . . . . . . . 
. . . # # . . . . . . @ . . . . . . . . . . . 
. . . . . . . . . . . . @ . . . . . . . . . . 
. . . . . . . . . . . . . @ . . . . . . . . . 
. . . . . . . . . . . . . . @ . . . . . . . . 
. . . . . . . . . . . . . . . @ . . . . . . . 
. . . . . . . . . . . . . . . . @ . . . . . . 
. . . . . . . . . . . . . . . . . @ . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
0 1 2 3 4 5 29 53 77 78 102 125 148 171 194 217 240 264 288 312 336 360 384 408 
duncanbritt@Duncans-MacBook-Pro maze-solver-c % ./example
32
32
65535
65535
65535
65535
@ @ @ @ @ @ . . . . . . . . . . . . . . . . . 
. . . . # # @ . . . . . . . . . . . . . . . . 
. . . . . # . @ . . . . . . . . . . . . . . . 
. . # # . # . . @ @ . . . . . . . . . . . . . 
. . . # # # . . . # @ . . . . . . . . . . . . 
. . . . . # . . . # @ . . . . . . . . . . . . 
. . . . . # # # # # @ . . . . . . . . . . . . 
. . . . . # # . . . @ . . . . . . . . . . . . 
. . . . . # . . . . @ . . . . . . . . . . . . 
. . . . # # . . . . @ . . . . . . . . . . . . 
. . . . # . . . . . @ . . . . . . . . . . . . 
. . . # # . . . . . . @ . . . . . . . . . . . 
. . . . . . . . . . . . @ . . . . . . . . . . 
. . . . . . . . . . . . . @ . . . . . . . . . 
. . . . . . . . . . . . . . @ . . . . . . . . 
. . . . . . . . . . . . . . . @ . . . . . . . 
. . . . . . . . . . . . . . . . @ . . . . . . 
. . . . . . . . . . . . . . . . . @ . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
0 1 2 3 4 5 29 53 77 78 102 125 148 171 194 217 240 264 288 312 336 360 384 408 
duncanbritt@Duncans-MacBook-Pro maze-solver-c % ./example
32
32
65535
65535
65535
65535
@ @ @ @ @ @ . . . . . . . . . . . . . . . . . 
. . . . # # @ . . . . . . . . . . . . . . . . 
. . . . . # . @ . . . . . . . . . . . . . . . 
. . # # . # . . @ @ . . . . . . . . . . . . . 
. . . # # # . . . # @ . . . . . . . . . . . . 
. . . . . # . . . # @ . . . . . . . . . . . . 
. . . . . # # # # # @ . . . . . . . . . . . . 
. . . . . # # . . . @ . . . . . . . . . . . . 
. . . . . # . . . . @ . . . . . . . . . . . . 
. . . . # # . . . . @ . . . . . . . . . . . . 
. . . . # . . . . . @ . . . . . . . . . . . . 
. . . # # . . . . . . @ . . . . . . . . . . . 
. . . . . . . . . . . . @ . . . . . . . . . . 
. . . . . . . . . . . . . @ . . . . . . . . . 
. . . . . . . . . . . . . . @ . . . . . . . . 
. . . . . . . . . . . . . . . @ . . . . . . . 
. . . . . . . . . . . . . . . . @ . . . . . . 
. . . . . . . . . . . . . . . . . @ . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . # # # # # # # 
0 1 2 3 4 5 29 53 77 78 102 125 148 171 194 217 240 264 288 312 336 360 384 408 

Is it possible there is something wrong with my code, or can I assume it is a problem with the library?

Yes, it is possible and likely that something is wrong with your code (that it exercises undefined behavior of some sort).

You should build your program with -fsanitize=address and make sure AddressSanitizer doesn't detect anything.

It is also possible (but unlikely ) that the build of ImageMagic you have is buggy.

PS

compiled like so: g++ -lstdc++ -std=c++11...

That command is bogus . You should remove -lstdc++ from it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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