This test example I've made works as expected:
FLAC__int32 array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
FLAC__int32 const *const handle(array);
FLAC__int32 temp[10];
std::vector<FLAC__int32> base;
base.resize(10);
memcpy(&base[0], handle, 10 * sizeof(FLAC__int32));
for (size_t i(0); i < 10; i++)
cout << endl << "[ " << i << " ] " << base[i];
However, with the code below, I can't get the memcpy to work correctly. How do I correct this so that memcpy makes correct copies of the buffer?
Note: _buffer contains binary data which was decoder by libFLAC.
FLAC__StreamDecoderWriteStatus
Source::write_callback
(FLAC__Frame const* _frame, FLAC__int32 const *const _buffer[])
{
cout << endl << "Head index [ " << index_ << " ].";
memcpy(&data_[index_], &_buffer[0], _frame->header.blocksize *
sizeof(FLAC__int32));
index_ += _frame->header.blocksize;
cout << endl << "Tail index [ " << index_ << " ].";
for(size_t i(0); i < 400; i++) {
cout << endl << "Buff [ " << i << " ] " << _buffer[i];
cout << endl << "Data [ " << i << " ] " << data_[i];
} // jump
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
} // main
And below is how I resize the vector and reset the index:
void
Source::metadata_callback (const ::FLAC__StreamMetadata *metadata)
{
...
total_samples_ = metadata->data.stream_info.total_samples;
...
data_.resize(total_samples_); index_ = 0;
} // main
You want a deep copy (that is, you want to copy the FLAC__int32 values, not the pointers to them), and you don't seem to care whether you construct a container of those values or of pointers to those values. So memcpy is the wrong tool. Let's start with a very simple case:
void foo(int * buf)
{
int data = *buf;
}
Then try copying an array to a vector:
void foo(int * buf[])
{
vector<int> data(10);
for(unsigned int k=0; k<3; ++k)
data[k] = *buf[k];
}
Then the full solution:
FLAC__StreamDecoderWriteStatus Source::write_callback(FLAC__Frame const* _frame, FLAC__int32 const *const _buffer[])
{
cout << endl << "Head index [ " << index_ << " ].";
data_.resize(_frame->header.blocksize);
for(size_t k=0; k<_frame->header.blocksize; ++k)
{
data_[index_+k] = *_buffer[k];
}
index_ += _frame->header.blocksize;
cout << endl << "Tail index [ " << index_ << " ].";
for(size_t i(0); i < 400; i++)
{
cout << endl << "Buff [ " << i << " ] " << *_buffer[i];
cout << endl << "Data [ " << i << " ] " << data_[i];
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
Related
So I am implementing a Benders procedure using lazy constraints from GUROBI. As part of the subproblem procedure I need to process a graph using Breadth First Search, for which I am using LEMON. I am trying to implement use a visitor for the BFS search. However when I try to access the map of reached nodes using bfs.reached() I get a compiler (I suppose) error.
Here is the callback class implementation so far:
typedef ListDigraph::Node Node;
typedef ListDigraph::Arc Arc;
typedef ListDigraph::ArcMap<double> ArcDou;
typedef ListDigraph::NodeMap<double> NodeDou;
typedef ListDigraph::ArcMap<int> ArcInt;
typedef ListDigraph::ArcMap<bool> ArcBool;
typedef ListDigraph::NodeMap<int> NodeInt;
typedef ListDigraph::NodeIt NodeIt;
typedef ReverseDigraph<ListDigraph>::NodeIt NodeIt_rev;
typedef ListDigraph::ArcIt ArcIt;
class BendersSub: public GRBCallback
{
public:
const Instance_data &ins;
const vec4GRBVar &X;
const vec1GRBvar &u;
vec2GRBVar &p;
GRBModel &modelSubD;
BendersSub(const Instance_data &ins, const vec4GRBVar &X, const vec1GRBvar &u, vec2GRBVar &p, GRBModel &modelSubD)
:ins(ins), X(X), u(u), p(p),modelSubD(modelSubD){
//cout << "\n\tI:" << ins.I << " J:" << ins.J << " T:" << ins.T << " V:" << ins.V << flush;
}
protected:
void callback() {
try {
if (where == GRB_CB_MIPSOL) {
cout << "\n -- Entering Callback -- " << flush;
string var_name;
int I = ins.I , J = ins.I , T = ins.T , V = ins.V,i,j,k,t,v;
ListDigraph grafo;
Node x;
for( int t(0); t < ins.T+1; t++)
for ( int i(0); i < ins.I; i++)
x = grafo.addNode();
Arc arco;
int count( 0 );
for(t = 0; t < ins.T; ++t){
for(i = 0; i < ins.I; ++i){
for(j = 0; j < ins.J; ++j){
if ( i == j ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(j + (ins.I * (t+1))));
}else if ( (t + ins.tau.at(i).at(j)) <= ins.T-1 ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(j + ins.I * (t + ins.tau.at(i).at(j))));
}
else if ( (t + ins.tau.at(i).at(j)) > ins.T-1 ){
arco = grafo.addArc(grafo.nodeFromId(i + ins.I * t),grafo.nodeFromId(((ins.I*(ins.T+1)+1))-1-(ins.I)+j)) ;
}
}
}
}
NodeDou divergence (grafo);
ArcDou costo (grafo);
ArcBool filter (grafo, true);
NodeDou potential (grafo);
ReverseDigraph<ListDigraph> grafo_r(grafo);
using Visitor = Visitor_AcSup<NodeDou>;
for ( int v(0); v < V; v++){
double sum_sup(0.0);
Visitor visitor(grafo_r, divergence, sum_sup);
cout << "\nsum_sup: " << sum_sup << flush;
for (t = 0; t < T; t++){
for(i = 0; i < I ; i++){
if(divergence[grafo.nodeFromId(flat_ixt(ins,t,i))] < -EPS3){
BfsVisit<ReverseDigraph<ListDigraph>, Visitor> bfs(grafo_r,visitor);
bfs.run(grafo.nodeFromId(flat_ixt(ins,t,i)));
if( (sum_sup-fabs(divergence[grafo.nodeFromId(flat_ixt(ins,t,i))])) < -EPS4 ){
cout << "\nBuild Ray" << flush;
}
}
}
}
for (NodeIt_rev u(grafo_r); u != INVALID; ++u){
/*The error does not show when I comment this line.*/
cout << "\nId: " << grafo.id(u) << setw(10) << bfs.reached(u) << flush;
}
cout << "\nsum_sup: " << sum_sup << flush;
.
/* Remaining code */
.
.
}/*end_if v*/
//cout << "\n -- Exiting Callback -- " << flush;
}
}catch (GRBException e) {
cout << "Error number: " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
exit(EXIT_FAILURE);
}catch (const exception &exc){
cerr << "\nCallback - " << exc.what() << flush;
exit(EXIT_FAILURE);
}catch (...) {
cout << "Error during callback" << endl;
exit(EXIT_FAILURE);
}
}
};
Here is the (incomplete visitor) implementation.
template <typename DivMap >
class Visitor_AcSup : public BfsVisitor< const ReverseDigraph<ListDigraph> > {
public:
Visitor_AcSup(const ReverseDigraph<ListDigraph>& _graph, DivMap& _dirMap, double& _sum_sup)
: graph(_graph), dirMap(_dirMap), sum_sup(_sum_sup){
cout << "\n --Calling constructor of Visitor_AcSup -- " << endl;
sum_sup = 0.0;
}
void start (const Node &node){
//cout << "\nstart Node: " << graph.id(node) << flush;
sum_sup -= dirMap[node];
}
void reach (const Node &node){
//cout << "\nReach Node: " << graph.id(node) << flush;
}
void process (const Node &node){
//cout << "\nProcess Node: " << graph.id(node) << setw(5) << dirMap[node] << flush;
sum_sup += dirMap[node];
}
void discover(const Arc& arc) {
//cout << "\tDiscover Arc: " << graph.id(arc) << flush;
}
void examine(const Arc& arc) {
//cout << "\tExamine Arc: " << graph.id(arc) << flush;
}
private:
const ReverseDigraph<ListDigraph>& graph;
DivMap& dirMap;
double& sum_sup;
The error looks like this
functions.cpp:1845:59: error: overloaded function with no contextual type information
cout << "\nId: " << grafo.id(u) << setw(10) << bfs.reached(u) << flush;
^~~~~~~
Makefile:27: recipe for target 'VAP' failed
I am clueless about what is happening as the only error that comes up to my mind is conflict of keywords between namespaces
using namespace lemon;
using namespace lemon::concepts;
using namespace std;
but have found no resolution to this. I am a newbie in C++, so that I am asking you guys where this could possibly come from.
In the following code, when run using GNU GCC v8.2.0, code does not terminate:
int main(void)
{
/* code */
int myArray[] = {2, 4};
int otherArray[] = {777, 888};
for(int i = 0; i<4; i++)
{
myArray[i] = 0;
cout << "myArray[" << i << "]=";
cout << myArray[i] << endl;
cout << "add: " << &myArray[i] << endl;
}
for(int i = 0; i<2; i++)
{
cout << "otherArray[" << i << "]=";
cout << otherArray[i] << endl;
cout << "add: " << &otherArray[i] << endl;
}
return 0;
}
output:
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]^C
for(int i = 0; i<4; i++)
Replace the 4 in the 'for loop' by 2 like this:
for(int i = 0; i<2; i++)
Since you're using a static array so it's better to specify the fixed size, but the most important is to be aware when you try to access the array by comparing the index being processed with the size of the array to avoid this behavior.
You are invoking undefined behaviour by writing the indexes 0-3 of the 2 element array myArray.
As this is undefined behaviour there are no guarantees as to what is happening or what will happen if you run the code again in the future. A likely explanation for your observed behaviour is that when you write myArray[2] that is actually overwriting the value of i causing your loop to restart back at 0.
The simple solution is to make myArray larger or change your for loop limit to 2.
To detect this sort of behaviour use std::array instead and call the at function which has bounds checking and will throw an exception when you go outside the bounds of the array. e.g.:
#include <array>
#include <iostream>
int main(void)
{
/* code */
std::array< int, 2 > myArray = { 2, 4 };
std::array< int, 2 > otherArray = { 777, 888 };
for(int i = 0; i<4; i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}
for(int i = 0; i<2; i++)
{
std::cout << "otherArray[" << i << "]=";
std::cout << otherArray.at(i) << "\n";
std::cout << "add: " << &otherArray.at(i) << "\n";
}
return 0;
}
std::array also has the bonus of a size() method which can make your code safer too:
for(int i = 0; i<myArray.size(); i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}
I'm having trouble getting the size of a vector by dot-walking from a parent vector into the one in question. I have verified that calling the function myfunc 1 2 3 4 5 creates five Person objects and puts them in the left vector. But when I try to get that same size to return by dot-walking from bridge to left, I get 0 as the size.
What am I doing wrong?
int main(int argc, char* argv[]) {
Person* p_ptr;
int id_source = 0;
vector<Person> left;
vector<Person> right;
bridge.push_back(left);
bridge.push_back(right);
cout << "bridge.size() = " << bridge.size() << endl;
for (int i = 1; i < argc; i++) {
id_source++;
cout << "Creating Person with crossing speed of " << argv[i] << " and id of " << id_source << endl;
p_ptr = new Person(atoi(argv[i]), id_source);
left.push_back(*p_ptr);
}
/*SIZE TESTING*/
cout << "Left side of bridge has " << left.size() << " people on it " << endl;
cout << "bridge.at(0).size() = " << bridge.at(0).size() << endl;
cout << "bridge.at(1).size() = " << bridge.at(1).size() << endl;
int slowest_id = get_slowest(0);
for (int i = 0; i < left.size(); i++) {
if (slowest_id == left.at(i).get_id()) {
p_ptr = &left.at(i);
}
}
cout << "The slowest person has id of " << slowest_id << " and speed of " << p_ptr->get_crossing_time() << endl;
}
}
left and bridge[0] are two different lists. When you call bridge.push_back(left) you make a copy of the current left list (which is empty). Elements added later will not be in the bridge version.
I have a simple main code that gives me segmentation fault when calling a function. In the following code, I have two functions, the first one works correctly but the program doesn't enter the second one and gives me segmentation fault error. Is there any reason for that? I have made sure about the following:
The variables o and c are not out of bound.
cn is initialized correctly.
I have a read-only access to cm and argv. Plus it does not even enter the function evaluate
Here is the code:
void print_cm(vector<vector<int> > *cm, char* gtf);
void evaluate(vector<vector<int> > *cm, char* gtf);
int main(int argc, char** argv)
{
int o = 2; // It is initialized
int c = 4; // It is initialized
vector<vector<int> > cm; // It is initialized
if (argc>4)
print_cm(&cm, argv[o]);
if (argc>4)
{
cout << argv[c] << endl; // Works
// The following also works
for (int i=0; i<cm.size(); i++)
for (int j=0; j<cm[i].size(); j++)
cout << cm[i][j] << " ";
// The following causes segmentation fault;
evaluate(&cm, argv[c]);
}
return 0;
}
void evaluate(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
void print_cm(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
Here is the complete code:
#include "includes/Utility.h"
#include "includes/Graph.h"
void print_cm(vector<vector<int> > *cores, char* output);
void evaluate(vector<vector<int> > const *cm, char* gtf);
int main(int argc, char** argv)
{
int g = -1, c = -1, o = -1;
for (int i=1; i<argc-1; i++)
if (argv[i][0]=='-')
{
if (argv[i][1]=='g')
g = i + 1;
else if (argv[i][1]=='c')
c = i + 1;
else if (argv[i][1]=='k')
ki = i + 1;
else if (argv[i][1]=='s')
si = i + 1;
else if (argv[i][1]=='o')
o = i + 1;
}
Graph G;
if (c>0) G.read_input(argv[g], argv[c]);
else G.read_input(argv[g]);
if (ki > 0)
{
int k = atoi(argv[ki]);
cout << k << endl;
}
if (si > 0)
{
int s = atoi(argv[si]);
cout << s << endl;
}
// Find communities
vector<vector<int> > cores;
G.partitioning(&cores);
if (o>0)
print_cm(&cores, argv[o]);
if (c>0)
{
cout << "here" << endl;
for (size_t i=0; i<cores.size(); i++)
for (size_t j=0; j<cores[i].size(); j++)
if (cores.at(i).at(j)<0) cout << "here";
cout << "here" << endl;
evaluate(&cores, argv[c]);
}
}
return 0;
}
void print_cm(vector<vector<int> > *cores, char* output)
{
ofstream out;
out.open(output);
for(size_t i=0; i<(*cores).size(); i++)
{
for(size_t j=0; j<(*cores)[i].size(); j++)
out << (*cores)[i][j] << " ";
out << endl;
}
out.close();
return ;
}
void evaluate(vector<vector<int> > const *cm, char* gtf)
{
// we evaluate precision, recall, F1 and F2
vector<vector<int> > gt;
ifstream in;
char str[100000000];
in.open(gtf);
while(in.getline(str, 100000000))
{
stringstream s;
s << str;
int a;
gt.resize(gt.size()+1);
while (s >> a) gt[gt.size()-1].push_back(a);
}
in.close();
cout << "==================== Evaluation Results ====================" << endl;
int imax = 0;
for(size_t i=0; i<(*cm).size(); i++)
imax = max(imax, *max_element((*cm)[i].begin(), (*cm)[i].end()));
for(size_t i=0; i<gt.size(); i++)
imax = max(imax, *max_element(gt[i].begin(), gt[i].end()));
vector<bool> flag(imax, false);
vector<double> recall((*cm).size(), 0), precision((*cm).size(), 0), f1((*cm).size(), 0), f2((*cm).size(), 0);
int overlap;
double size = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
// evaluate
size += (double) (*cm)[i].size();
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = true;
double p, r, ff1, ff2;
for(size_t j=0; j<gt.size(); j++)
{
overlap = 0;
for(size_t k=0; k<gt[j].size(); k++)
if (flag[gt[j][k]]) overlap++;
p = (double) overlap / (double) (*cm)[i].size();
if (p > precision[i])
precision[i] = p;
r = (double) overlap / (double) gt[j].size();
if (r > recall[i])
recall[i] = r;
ff1 = (double) 2*(p*r)/(p+r);
if (ff1 > f1[i])
f1[i] = ff1;
ff2 = (double) 5*(p*r)/(4*p + r);
if (ff2 > f2[i])
f2[i] = ff2;
}
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = false;
}
double Recall = 0, Precision = 0, F1 = 0, F2 = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
Recall += recall[i];
Precision += precision[i];
F1 += f1[i];
F2 += f2[i];
}
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << "Precision";
cout << " | " << setiosflags( ios::left ) << setw(10) << "Recall";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F1-measure";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F2-measure";
cout << " |" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << Precision/(*cm).size() ;
cout << " | " << setiosflags( ios::left ) << setw(10) << Recall/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F1/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F2/(*cm).size();
cout << " |" << endl;
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "Number of communities: " << (*cm).size() << endl;
cout << "Average community size: " << size/(*cm).size() << endl;
return ;
}
char str[100000000];
This is in your evaluate function. This are 100 million bytes, or about 95 MB that you're allocating on the stack.
Typical stack sizes are far less than that, around 1 MB.
So apart from possible other problems this is most likely causing a stack overflow.
When entering the function, the stack frame gets extended to be large enough to hold the local variables. As soon as the stack is used then (to write a default value) you're accessing invalid (non stack, thankfully protected) memory.
I don't understand how fix this problem, tried many things but no solution. Help on it would be much appreciated. Thanks.
Error 1 error C2664: 'void showAllBuses(const Bus *[],int)' : cannot convert argument 1 from 'Bus **' to 'const Bus *[]'
void showAllBuses(const Bus* pBuses[], int numBus) {
for (int i = 0; i < numBus; i++) {
cout << "Bus no ." << numBus << " details: " << endl;
cout << "Number: " << pBuses[i]->getNumber() << endl;
cout << "Driver name: " << pBuses[i]->getDriver().getName() << endl;
cout << "Driver experience(years): " << pBuses[i]->getDriver().getYearsDriving() << endl;
}
}
void listBusesWithYearsDriving(const Bus* pBuses[], int numBus, int drivingYears) {
for (int i = 0; i < numBus; i++) {
if (pBuses[i]->getDriver().getYearsDriving() >= drivingYears) {
cout << "Bus number: " << pBuses[i]->getNumber() << endl;
cout << "Driver name: " << pBuses[i]->getDriver().getName() << endl;
cout << "Driver experience: " << pBuses[i]->getDriver().getYearsDriving() << endl;
}
}
}
void removeDriver(Bus* pBuses[], int busPos) {
pBuses[busPos]->removeDriver();
}
void main() {
const int ASIZE = 4;
int drivingYears = 0;
Bus* buses = new Bus[ASIZE];
for (int i = 0; i < ASIZE; i++) {
addNewBus(&buses[i]);
cout << "Bus " << i << ": " << &buses[i] << endl;
}
showAllBuses(&buses, ASIZE);
cout << "Please enter a minimum years of experience to look for: " << endl;
cin >> drivingYears;
listBusesWithYearsDriving(&buses, ASIZE, drivingYears);
removeDriver(&buses, 0);
showAllBuses(&buses, ASIZE);
delete[] buses;
buses = nullptr;
cout << "\n\n";
system("pause");
}
For any type T, T* can be implicitly converted to const T*, but T** cannot be implicitly converted to const T**. Allowing this would make it possible to violate constness(1).
A T ** can be converted to const T* const *, though. Since your function does not modify the array in any way, you can simply change its parameter like that:
void showAllBuses(const Bus* const * pBuses, int numBus) {
Bear in mind that in a function parameter declaration, * and the outermost [] are synonyms.
(1) Here's the code:
const int C = 42;
int I = -42;
int *p = &I;
int *pp = &p;
const int **cp = pp; // error here, but if it was allowed:
*cp = &C; // no problem, *cp is `const int *`, but it's also `p`!
*p = 0; // p is &C!