need help understaning a gdb error

Pages: 12

I have two typedefs for a vector:
1
2
typedef std::vector<bool> bit_vector;
typedef const std::vector<bool> const_bit_vector;

and that vector is filled like this:
1
2
 
bit_vector decoded_lcw_vec(corrected_array, corrected_array + sizeof corrected_array / sizeof corrected_array[0]) ; 

the function i am trying to use to read the vector:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * Extract value of bits from in[bits[0..bits_sz)).
 *
 * \param in A const reference to the source.
 * \param bits An array specifying the ordinals of the bits to extract.
 * \param bits_sz The size of the bits array.
 * \return A uint64_t containing the value
 */
template<class X>
uint64_t extract(const X& in, const size_t bits[], size_t bits_sz)
{
   uint64_t x = 0LL;
   for(size_t i = 0; i < bits_sz; ++i) {
      x =  (x << 1) | (in[bits[i]] ? 1 : 0);
   }
   return x;
}


I give the above function its first argument (the vector) via function call:
1
2
3
4
5
6
7
8
  const uint16_t lcf = extract(get_vec(), LCF_BITS, LCF_BITS_SZ);

//returns the vector as a constant reference to the source
const_bit_vector&
ldu1::get_vec() const
{
  return decoded_lcw_vec;
}


And finally the error i get from the core file:
1
2
3
4
5
 (gdb) frame 0
#0  extract<std::vector<bool, std::allocator<bool> > > (in=..., 
    bits=bits@entry=0xa322bce0, bits_sz=bits_sz@entry=8) at ./op25_yank.h:109
109	      x =  (x << 1) | (in[bits[i]] ? 1 : 0);


I have no idea what to try next. any help will be much appreciated.
http://www.eelis.net/iso-c++/testcase.xhtml

Check for out of bounds access. You may benefit from by creating intermediate steps instead of one big sentence.

Also, ┬┐couldn't you simply use bitset http://www.cplusplus.com/reference/bitset/bitset/to_ullong/ ?
yeah bitset would make sense but i should keep with the convention that is already in place. i think. what is out of bounds access??
edit: ok ok so i looked up out of bounds. i sort of get it. but how could i be doing something out of bounds? certainly not filling the vector right? i use the extract function like this:

1
2
3
4
5
6
7
8
9
10
uint16_t 
ldu1::lcf() const
{
   const size_t LCF_BITS[] = {
      0, 1, 2, 3, 4, 5, 6 , 7
   };
   const size_t LCF_BITS_SZ = sizeof(LCF_BITS) / sizeof(LCF_BITS[0]);
   const uint16_t lcf = extract(get_vec(), LCF_BITS, LCF_BITS_SZ);
   return lcf;
}

so i am telling extract to take the values in ordinals 0,1,2,3,4,5,6,7 of the vector. i dont know how this could be out of range?
Last edited on
i still can not make heads or tails of why the program seg faults. any help will be much appreciated.
make a testcase
making a test case will be impossible because the file i am working on includes 13 other headers those probably include another 5 each. there are templates and typedefs as well. any suggestion?
Last edited on
┬┐simplify?
You can upload it to github if you want. The idea is for others to be able to reproduce your issue.
right. ill have to try to whittle it down and upload it. currently i believe that there is something wrong with the vector i am trying to give to the extract function. is it ok to fill a <bool>vector with values from an array typed 'int' ?
I tend to forget the consequences of the vector<bool> specialization, sorry.
i hear you. some say vector<bool> is buggy and can produce undefined behavior so i don't know if i can believe what i read about it.
do you know how i can print this vector?? so i can lay eyes on its contents? i have not found a way to print a bool value.
 
 for(int i = 0 ; i < 96; i++ )  printf("%c", decoded_lcw_vec[i]) ;

prints diamonds or seg faults and type "%d" makes a seg fault. Thanks!
Last edited on
std::cout << std::boolalpha << decoded_lcw_vec[i] << ' '; gives true/false
Or simply std::cout << decoded_lcw_vec[i] << ' '; for 0/1
What is the size of your vector? I would guess it's too small.

Try the at()
1
2
3
   for(size_t i = 0; i < bits_sz; ++i) {
      x =  (x << 1) | (in.at(bits[i]) ? 1 : 0);
   }

Now your code will throw an exception if its a problem with the vector.

Edit: You should be able to print contents of the vector from within gdb
Last edited on
the vector should hold 72 bits. i start by creating an array:
1
2
3
4
5
6
7
8
9
int corrected_array[72] = {0};  
    for ( i=0; i<12; i++) //error corrected "hex-bits" back to binary
    {
        for ( j = 0; j<6; j++)
        {
            int mask = 1 << (5 - j);
            corrected_array[i*6 + j] = ((recd[12+i] & mask) != 0);
        }
    }

the correct 72 bits are there:

corrected_array[]:000000000000000001000000000000000000000000000001001000100000011111110110

and then i convert the array to a vector:
 
bit_vector decoded_lcw_vec(corrected_array, corrected_array + sizeof corrected_array / sizeof corrected_array[0]) ; 

right now i am testing the with the cout instead of printf() to see if i can see whats in it. thanks.

I'm not having problems with anything you posted.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <vector>
#include <cstdint>

// because I don't have recd
#include <ctime>
#include <cstdlib>

// to print something quick
#include <iterator>
#include <algorithm>


std::vector< bool > get_vec( void )
{
  int corrected_array[72] = {0};
  for ( int i=0; i<12; i++) //error corrected "hex-bits" back to binary
  {
    for ( int j = 0; j<6; j++)
    {
      int mask = 1 << (5 - j);
      corrected_array[i*6 + j] = rand() % 2 ;
    }
  }

  std::vector<bool> ret( corrected_array, corrected_array + 72 );
  std::copy( ret.begin(), ret.end(), std::ostream_iterator<bool>( std::cout, "" ));
  std::cout << std::endl;
  return ret;
}

template<class X>
uint64_t extract(const X& in, const size_t bits[], size_t bits_sz)
{
  uint64_t x = 0LL;
  for(size_t i = 0; i < bits_sz; ++i) {
    x =  (x << 1) | (in[bits[i]] ? 1 : 0);
  }
  return x;
}

uint16_t lcf( void )
{
  const size_t LCF_BITS[] = {
  0, 1, 2, 3, 4, 5, 6 , 7
  };
  const size_t LCF_BITS_SZ = sizeof(LCF_BITS) / sizeof(LCF_BITS[0]);
  const uint16_t lcf = extract(get_vec(), LCF_BITS, LCF_BITS_SZ);
  return lcf;
}

int main( void )
{
  srand( time(0) );
  std::cout << lcf() << std::endl;
  return 0;
}
alright so i am getting correct values out of the vector:

Decode LDU1 LCW Vector Complete:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1 

so maybe the way i am passing the vector in to the extract function is wrong? the vector is declared private in the .h file. so if i use a function to return the vector as shown above:
1
2
3
4
5
6
7
8
  const uint16_t lcf = extract(get_vec(), LCF_BITS, LCF_BITS_SZ);

//returns the vector as a constant reference to the source
const_bit_vector&
ldu1::get_vec() const
{
  return decoded_lcw_vec;
}

this should work right?
That works
I am still getting the seg fault and i have been unable to figure out why. any ideas?
some say vector<bool> is buggy and can produce undefined behavior so i don't know if i can believe what i read about it.

It's not buggy - unless you're using a bad implementation of the standard library - but it does behave differently from vectors of other types, as defined in the C++ standard.

Have a look at the reference documentation on this site for information.

Edit: Since you're running it in a debugger (gdb), you can see exactly where it crashes and what the state of the memory is. Unfortunately, gdb is rather user-unfriendly - can you try using a more easy-to-use debugger?

Edit 2: There's no harm in refactoring the code to make it easier to test. In fact, I'd say that's almost always a good thing to do.
Last edited on
something has got to be wrong with the vector, or how I am trying to get it into the other functions, although I do not know what. Trying to access the vector in another function from where it is filled makes the program stumble. from gdb we can see that simply trying to print the vector in an other function kills the program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Program terminated with signal 11, Segmentation fault.
#0  operator bool (this=<optimized out>)
    at /usr/include/c++/4.7/bits/stl_bvector.h:82
82	    { return !!(*_M_p & _M_mask); }
(gdb) bt
#0  operator bool (this=<optimized out>)
    at /usr/include/c++/4.7/bits/stl_bvector.h:82
#1  operator* (this=<optimized out>)
    at /usr/include/c++/4.7/bits/stl_bvector.h:288
#2  operator[] (__n=0, this=<optimized out>)
    at /usr/include/c++/4.7/bits/stl_bvector.h:712
#3  ldu1::lcf (this=0xaf702010) at ldu1.cc:137  //where the print statement is
#4  0xb2d4ea01 in ldu1::snapshot (this=0xaf702010) at ldu1.cc:102
#5  0xb2d539ab in snapshot_du_handler::handle (this=0xa8ffcf0, du=...)
    at snapshot_du_handler.cc:44
#6  0xaf703aa4 in ?? () 

Some say vector<bool> cannot be trusted, but I think they are wrong because I see it works well in the rest of the program. But I am using it in a very similar way. How can I safely get the vector from one function to another without putting it in as a function parameter?

and here is the function where the print is:
1
2
3
4
5
6
7
8
9
10
uint16_t 
ldu1::lcf() const
{    
    int i;
    uint16_t lcf;
    printf("\n      LCF:  ");
    for(i=0; i<8; i++) cout << decoded_lcw_vec[i];
    for(i=0; i<8; i++) lcf = decoded_lcw_vec[i];
    return lcf;
}
Last edited on
Pages: 12