Reputation: 389
I've been trying to find a really function that let me convert from std::vector of vector to igraph_vector_ptr_t and the opposite way.
The reason is, there are different classes like a std::sort, std::unique and others, that let us manipulate vectors, this function do not exist in Igraph libraries.
The next code only show the code to convert from std::vector to igraph_vector_ptr_t, the problem is that it doesn't work, please help me to help me to improve it.
#include <igraph.h>
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
void print_vector(igraph_vector_t *v, FILE *f) {
long int i;
long int l=igraph_vector_size(v);
for (i=0; i<l; i++) {
fprintf(f, " %li", (long int) VECTOR(*v)[i]);
}
fprintf(f, "\n");
}
void Stl_To_Igraph_vector_ptr_t(std::vector< std::vector< long int > > & vectR, igraph_vector_ptr_t * vl) {
long int i,j,n;
igraph_vector_t vt;
igraph_vector_init(&vt,4);
for (i = 0; i< 2; i++) {
for (j = 0; j< 4; j++) {
//cout << vectR.at(i).at(j) << " ";
VECTOR(vt)[j]=vectR.at(i).at(j);
}
//cout<<endl;
igraph_vector_ptr_set(vl, i,&vt);
}
}
int main() {
// Set STL Vectors
std::vector< std::vector< long int > > vectR;
std::vector<long int> vectRi1,vectRi2;
long int myarray1 [] = { 1,2,3,4 };
long int myarray2 [] = { 5,6,7,8 };
vectRi1.insert(vectRi1.begin(), myarray1, myarray1+4);
vectRi2.insert(vectRi2.begin(), myarray2, myarray2+4);
vectR.push_back(vectRi1);
vectR.push_back(vectRi2);
// Convert From Stl vector to Igraph_vector_ptr_t
igraph_vector_ptr_t vIgraph;
igraph_vector_ptr_init(&vIgraph, 2);
Stl_To_Igraph_vector_ptr_t(vectR, &vIgraph);
// Print and distroyed
long int i;
for (i=0; i<igraph_vector_ptr_size(&vIgraph); i++) {
print_vector((igraph_vector_t *)VECTOR(vIgraph)[i],stdout);
igraph_vector_destroy((igraph_vector_t *)VECTOR(vIgraph)[i]);
free((igraph_vector_t *)VECTOR(vIgraph)[i]);
}
return 0;
}
Ok this is part of the solution but I have a problem in valgrind,
#include <igraph.h>
#include <stdlib.h>
int print_vector(igraph_vector_t *v) {
long int i, l=igraph_vector_size(v);
for (i=0; i<l; i++) {
printf(" %li", (long int) VECTOR(*v)[i]);
}
printf("\n");
}
void convert(igraph_vector_ptr_t * vecs){
long int i,j;
igraph_vector_t *v;
v = (igraph_vector_t*)calloc(igraph_vector_ptr_size(vecs), sizeof(igraph_vector_t));
for(i=0; i<igraph_vector_ptr_size(vecs); i++)
{
igraph_vector_init(v + i,10);
for(j=0; j<igraph_vector_size(v); j++){
VECTOR(*(v+i))[j]=i+j;
}
igraph_vector_ptr_set(vecs,i,(v + i));
}
}
int main() {
igraph_vector_ptr_t vecs;
long int i;
igraph_vector_ptr_init(&vecs, 3);
for (i=0; i<igraph_vector_ptr_size(&vecs); i++) {
VECTOR(vecs)[i] = malloc(sizeof(igraph_vector_t));
igraph_vector_init( (igraph_vector_t*)VECTOR(vecs)[i], 3);
}
convert(&vecs);
for (i=0; i<igraph_vector_ptr_size(&vecs); i++) {
print_vector( (igraph_vector_t*)VECTOR(vecs)[i]);
igraph_vector_destroy( (igraph_vector_t*)VECTOR(vecs)[i]);
//free(VECTOR(vecs)[i]);
}
igraph_vector_ptr_destroy(&vecs);
return 0;
}
and the output of valgrind is:
user@pc:~/workSpalceIgraphCpp/proyIgraph$ valgrind --leak-check=full -v --track-origins=yes --show-reachable=yes ./example
==12439== Memcheck, a memory error detector
==12439== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==12439== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==12439== Command: ./example
==12439==
--12439-- Valgrind options:
--12439-- --suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp
--12439-- --leak-check=full
--12439-- -v
--12439-- --track-origins=yes
--12439-- --show-reachable=yes
--12439-- Contents of /proc/version:
--12439-- Linux version 2.6.32-35-generic-pae (buildd@vernadsky) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) ) #78-Ubuntu SMP Tue Oct 11 17:01:12 UTC 2011
--12439-- Arch and hwcaps: X86, x86-sse1-sse2
--12439-- Page sizes: currently 4096, max supported 4096
--12439-- Valgrind library directory: /usr/lib/valgrind
--12439-- Reading syms from /lib/ld-2.11.1.so (0x4000000)
--12439-- Reading debug info from /lib/ld-2.11.1.so ..
--12439-- .. CRC mismatch (computed 45f50ae1 wanted 137bc614)
--12439-- Reading debug info from /usr/lib/debug/lib/ld-2.11.1.so ..
--12439-- Reading syms from /home/rvaca/workSpalceIgraphCpp/proyIgraph/example (0x8048000)
--12439-- Reading syms from /usr/lib/valgrind/memcheck-x86-linux (0x38000000)
--12439-- object doesn't have a dynamic symbol table
--12439-- Reading suppressions file: /usr/lib/valgrind/debian-libc6-dbg.supp
--12439-- Reading suppressions file: /usr/lib/valgrind/default.supp
--12439-- REDIR: 0x40160b0 (index) redirected to 0x3803e9b3 (vgPlain_x86_linux_REDIR_FOR_index)
--12439-- Reading syms from /usr/lib/valgrind/vgpreload_core-x86-linux.so (0x401f000)
--12439-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so (0x4022000)
==12439== WARNING: new redirection conflicts with existing -- ignoring it
--12439-- new: 0x040160b0 (index ) R-> 0x04025c30 index
--12439-- REDIR: 0x4016290 (strlen) redirected to 0x4026070 (strlen)
--12439-- Reading syms from /usr/local/lib/libigraph.so.0.0.0 (0x402b000)
--12439-- Reading syms from /usr/lib/libstdc++.so.6.0.13 (0x4213000)
--12439-- object doesn't have a symbol table
--12439-- Reading syms from /lib/tls/i686/cmov/libm-2.11.1.so (0x4308000)
--12439-- Reading debug info from /lib/tls/i686/cmov/libm-2.11.1.so ..
--12439-- .. CRC mismatch (computed a765a73c wanted 8d13be57)
--12439-- Reading debug info from /usr/lib/debug/lib/tls/i686/cmov/libm-2.11.1.so ..
--12439-- Reading syms from /lib/libgcc_s.so.1 (0x432e000)
--12439-- Reading debug info from /lib/libgcc_s.so.1 ..
--12439-- .. CRC mismatch (computed 338494ad wanted b1d69d39)
--12439-- object doesn't have a symbol table
--12439-- Reading syms from /lib/tls/i686/cmov/libc-2.11.1.so (0x434d000)
--12439-- Reading debug info from /lib/tls/i686/cmov/libc-2.11.1.so ..
--12439-- .. CRC mismatch (computed 2236eb0a wanted a071c0c3)
--12439-- Reading debug info from /usr/lib/debug/lib/tls/i686/cmov/libc-2.11.1.so ..
--12439-- Reading syms from /usr/lib/libxml2.so.2.7.6 (0x44a8000)
--12439-- Reading debug info from /usr/lib/libxml2.so.2.7.6 ..
--12439-- .. CRC mismatch (computed 8c0a5cb7 wanted d9f96831)
--12439-- object doesn't have a symbol table
--12439-- Reading syms from /usr/lib/libgmp.so.3.5.2 (0x45d3000)
--12439-- Reading debug info from /usr/lib/libgmp.so.3.5.2 ..
--12439-- .. CRC mismatch (computed b9cf7786 wanted 4db0a849)
--12439-- object doesn't have a symbol table
--12439-- Reading syms from /lib/tls/i686/cmov/libdl-2.11.1.so (0x4634000)
--12439-- Reading debug info from /lib/tls/i686/cmov/libdl-2.11.1.so ..
--12439-- .. CRC mismatch (computed 10f03463 wanted f15a6db6)
--12439-- Reading debug info from /usr/lib/debug/lib/tls/i686/cmov/libdl-2.11.1.so ..
--12439-- Reading syms from /lib/libz.so.1.2.3.3 (0x4638000)
--12439-- Reading debug info from /lib/libz.so.1.2.3.3 ..
--12439-- .. CRC mismatch (computed 53909dc3 wanted dc0e37c9)
--12439-- object doesn't have a symbol table
--12439-- REDIR: 0x43c0b10 (rindex) redirected to 0x4025ae0 (rindex)
--12439-- REDIR: 0x43c07f0 (__GI_strlen) redirected to 0x4026050 (__GI_strlen)
--12439-- REDIR: 0x43bc660 (calloc) redirected to 0x402417f (calloc)
--12439-- REDIR: 0x43bcf40 (malloc) redirected to 0x4024e9b (malloc)
--12439-- REDIR: 0x43c32b0 (strchrnul) redirected to 0x4027510 (strchrnul)
0 1 2 3 4 5 6 7 8 9
--12439-- REDIR: 0x43bce60 (free) redirected to 0x4024ab5 (free)
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 11
==12439==
==12439== HEAP SUMMARY:
==12439== in use at exit: 144 bytes in 7 blocks
==12439== total heap usage: 11 allocs, 4 frees, 396 bytes allocated
==12439==
==12439== Searching for pointers to 7 not-freed blocks
==12439== Checked 425,428 bytes
==12439==
==12439== 36 bytes in 1 blocks are definitely lost in loss record 1 of 3
==12439== at 0x402425F: calloc (vg_replace_malloc.c:467)
==12439== by 0x80488C8: convert(s_vector_ptr*) (pregunta3.cpp:223)
==12439== by 0x8048A11: main (pregunta3.cpp:246)
==12439==
==12439== 72 bytes in 3 blocks are indirectly lost in loss record 2 of 3
==12439== at 0x402425F: calloc (vg_replace_malloc.c:467)
==12439== by 0x40C9A78: igraph_vector_init (vector.pmt:123)
==12439== by 0x80489E9: main (pregunta3.cpp:243)
==12439==
==12439== 108 (36 direct, 72 indirect) bytes in 3 blocks are definitely lost in loss record 3 of 3
==12439== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==12439== by 0x80489C8: main (pregunta3.cpp:242)
==12439==
==12439== LEAK SUMMARY:
==12439== definitely lost: 72 bytes in 4 blocks
==12439== indirectly lost: 72 bytes in 3 blocks
==12439== possibly lost: 0 bytes in 0 blocks
==12439== still reachable: 0 bytes in 0 blocks
==12439== suppressed: 0 bytes in 0 blocks
==12439==
==12439== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 27 from 6)
--12439--
--12439-- used_suppression: 27 dl-hack3-cond-1
==12439==
==12439== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 27 from 6)
what's the problem?
Upvotes: 0
Views: 1001
Reputation: 48071
First of all, igraph is a C library, not a C++ library. C does not have anything like the STL, so that's why there are no conversion functions between an igraph_vector_t
and an std::vector
. You have to write the conversion functions yourself.
Second, since vt
is a vector allocated on the stack within Stl_To_Igraph_vector_ptr_t
(i.e. you just declared it as a local variable and did not allocate it using malloc
), it will cease to exist as soon as the function returns. You store a pointer to vt
in your igraph_vector_ptr_t
, but that pointer becomes invalid when you exit from the function, that's why you are getting an error later. You have to make vt
an igraph_vector_ptr_t
, and use malloc
to allocate it if you want it to outlive the conversion function.
Edit: This is how it should be done -- I haven't tested it though (no C compiler around), but it should work. These are optimized for readability and not for performance (e.g. you could do Stl_To_Igraph_vector_T
using std::copy
):
void Stl_To_Igraph_vector_t(std::vector<long int>& vectR, igraph_vector_t* v) {
size_t n = vectR.size();
/* Make sure that there is enough space for the items in v */
igraph_vector_resize(v, n);
/* Copy all the items */
for (size_t i = 0; i < n; i++) {
VECTOR(*v)[i] = vectR[i];
}
}
void Stl_To_Igraph_vector_ptr_t(std::vector< std::vector<long int> >& vectR, igraph_vector_ptr_t* vl) {
size_t n = vectR.size();
/* Make sure that there is enough space for the items in vl */
igraph_vector_ptr_resize(vl, n);
/* Copy all the items */
for (size_t i = 0; i < n; i++) {
VECTOR(*vl)[i] = (igraph_vector_t*)malloc(sizeof(igraph_vector_t));
igraph_vector_init(VECTOR(*vl)[i]);
Stl_To_Igraph_vector_t(vectR[i], VECTOR(*vl)[i]);
}
}
vl
must be initialized to zero size before calling Stl_To_Igraph_vector_ptr_t
. When you are done with using vl
, you must call igraph_vector_destroy
and free
on all its elements.
Upvotes: 1