Open chtenb opened 7 years ago
I can reproduce this problem on Linux using this hacked C version
work:bug1199$ cat test.c
#include <string.h>
#include <stdlib.h>
#include <gvc.h>
#include <cgraph.h>
#include <cdt.h>
void dump(Agraph_t* root, char* filename)
{
GVC_t* gvc = gvContext();
// imagwrite(root, (filename + ".dot").c_str());
gvLayout(gvc, root, "dot");
gvRenderFilename(gvc, root, "png", filename);
}
void main()
{
Agraph_t* root = agopen("test root graph", Agdirected, NULL);
Agnode_t* n1 = agnode(root, "x", 1);
Agnode_t* n2 = agnode(root, "xx", 1);
Agnode_t* n3 = agnode(root, "xxx", 1);
Agnode_t* n4 = agnode(root, "xxxx", 1);
agedge(root, n2, n4, "1", 1);
agedge(root, n3, n4, "1", 1);
agedge(root, n1, n2, "1", 1);
agedge(root, n2, n1, "2", 1);
agedge(root, n1, n3, "1", 1);
agedge(root, n3, n1, "2", 1);
agedge(root, n2, n3, "1", 1);
agedge(root, n3, n2, "2", 1);
dump(root, "dump1.png");
agdelete(root, n1);
dump(root, "dump2.png");
}
work:bug1199$ cat Makefile
CFLAGS=-I/usr/include/graphviz
LDFLAGS=-lgvc -lcgraph -lcdt
test: test.c
Now the question is whats wrong with agdelete() ?
.
OK, I don't think its a problem with agdelete(). Adding: gvFreeLayout(gvc, root); gvFreeContext(gvc); seems to fix the problem.
work:bug1199$ cat test.c
#include <string.h>
#include <stdlib.h>
#include <gvc.h>
#include <cgraph.h>
#include <cdt.h>
void dump(Agraph_t* root, char* filename)
{
GVC_t* gvc = gvContext();
// imagwrite(root, (filename + ".dot").c_str());
gvLayout(gvc, root, "dot");
gvRenderFilename(gvc, root, "png", filename);
gvFreeLayout(gvc, root);
gvFreeContext(gvc);
}
void main()
{
Agraph_t* root = agopen("test root graph", Agdirected, NULL);
Agnode_t* n1 = agnode(root, "x", 1);
Agnode_t* n2 = agnode(root, "xx", 1);
Agnode_t* n3 = agnode(root, "xxx", 1);
Agnode_t* n4 = agnode(root, "xxxx", 1);
agedge(root, n2, n4, "1", 1);
agedge(root, n3, n4, "1", 1);
agedge(root, n1, n2, "1", 1);
agedge(root, n2, n1, "2", 1);
agedge(root, n1, n3, "1", 1);
agedge(root, n3, n1, "2", 1);
agedge(root, n2, n3, "1", 1);
agedge(root, n3, n2, "2", 1);
dump(root, "dump1.png");
agdelete(root, n1);
dump(root, "dump2.png");
}
I believe it is necessary to call gvFreeLayout. This documented in http://www.graphviz.org/doc/libguide/libguide.pdf.
I believe it is necessary to call gvFreeLayout. This documented in http://www.graphviz.org/doc/libguide/libguide.pdf.
You are entirely correct. Is it possible to check for an existing layout right before a new layout is computed? We could then free the existing one to prevent bugs like these from happening.
Consider the following bit of test code.
dump1.png:![dump1](https://cloud.githubusercontent.com/assets/1030961/22247434/17b9415c-e23a-11e6-8ee6-bfc04f87b547.png)
dump2.png:![dump2](https://cloud.githubusercontent.com/assets/1030961/22247435/17bafc90-e23a-11e6-9c1d-642077b66569.png)
As you see, there are two seemingly stale edges partially visible in dump2.png that I wouldn't expect there. The contents of the dot dumps is as follows.
dump1.dot:
dump2.dot:
As you see there is no trace of these stale edges in the dot representation. This seems like a bug to me, or am I doing something wrong?
The identifiers
imagwrite
andmemDisc
have to do with the custom IO discipline I'm using. If needed I can upload the discipline code as well.