Using std::vector with Igraph

Using std::vector with Igraph

本文关键字:Igraph with vector Using std      更新时间:2023-10-16

我一直在试图找到一个真正的函数,让我从 std::vector 的矢量转换为 igraph_vector_ptr_t 和相反的方式。

原因是,有不同的类,如 std::sort、std::unique 等,让我们操作向量,这个函数在 Igraph 库中不存在。

下一个代码仅显示从 std::vector 转换为 igraph_vector_ptr_t 的代码,问题是它不起作用,请帮助我帮助我改进它。

#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;
}

好的,这是解决方案的一部分,但我在瓦尔格林德遇到了问题,

#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;
}

瓦尔格林德的输出是:

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)

怎么了?

首先,igraph 是一个 C 库,而不是一个C++库。C 没有像 STL 那样的东西,所以这就是为什么igraph_vector_tstd::vector之间没有转换函数的原因。您必须自己编写转换函数。

其次,由于vtStl_To_Igraph_vector_ptr_t内堆栈上分配的向量(即您只是将其声明为局部变量并且没有使用malloc分配它),一旦函数返回,它将不复存在。您在igraph_vector_ptr_t中存储指向vt的指针,但是当您退出函数时,该指针将变为无效,这就是您稍后收到错误的原因。你必须使vt成为igraph_vector_ptr_t,如果你想让它比转换函数活下去,malloc来分配它。

编辑:这就是它应该完成的方式 - 我还没有测试它(周围没有C编译器),但它应该可以工作。这些针对可读性而不是性能进行了优化(例如,您可以使用std::copy来执行Stl_To_Igraph_vector_T):

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]);
    }
}

在调用 Stl_To_Igraph_vector_ptr_t 之前,必须将vl初始化为零大小。当你使用完vl 时,你必须调用 igraph_vector_destroy 对其所有元素进行free