Circular List Traversal Engine - c++

I want to traverse a circular linked list (v1->v2->v3) in a given input order, lets say like
{v1,v3,v2,v2,v1,v3,v2,v1,v1,v3,v2,v2,v1,v2,v3}.
I wrote the below program as test for 3 nodes and would like to scale incrementally for 8, 64, 512, 4096, etc. nodes.
My idea of implementation requires the below program to run solely on an Abstract State Machine which only accepts the below functions as input for processing. I basically want to minimise the loop count of engine_spin_at_gear() while traversing. I may be on a non-blocking mode for using such an insane abstraction to mimic/virtualize process-execution as an engine-spin with unit of measurement as rpm, but I would really like suggestions on debugging the engine_spin_at_gear() function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MILES 15
struct package
{
// ... other members data ...
struct package *next;
}*v1, *v2, *v3;
int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3};
struct package *base(struct package *_vN)
{
if (_vN)
return _vN;
else
return NULL;
}
struct package *deliver(struct package *_vNP)
{
if (_vNP)
return base(_vNP->next);
else
return NULL;
}
void shift_gear(struct package *_feed)
{
_feed->next = NULL;
}
struct package *engine_spin_at_gear(struct package *_init_cycle0, int countSession)
{
while (countSession--) {
shift_gear(_init_cycle0);
return deliver(base(_init_cycle0));
}
return NULL;
}
struct package *journey(struct package *_current_frame, int _start, int _end)
{
int rpm = (_end > _start)?_end-_start:_start-_end;
if (rpm)
return engine_spin_at_gear(_current_frame, rpm);
else
return v1;
}
struct package *ignition_phase(int _batteryS, int _chargedL)
{
return journey(v1, _batteryS, _chargedL);
}
void transmit_in_order(int*input_arr)
{
struct package *v6;
int i;
for (i=0; i<MILES-1; i++) {
v6 = ignition_phase(input_arr[i], input_arr[i+1]);
printf("%p\n", v6);
}
}
int main()
{
v1 = malloc(sizeof(struct package));
v2 = malloc(sizeof(struct package));
v3 = malloc(sizeof(struct package));
v1->next = v2;
v2->next = v3;
v3->next = v1;
printf("v1=%p\tv2=%p\tv3=%p\n", v1, v2, v3);
transmit_in_order(input_arr);
return 0;
}
I am getting the following output when I ran my program's GCC executable on Linux.
v1=0x918b008 v2=0x918b018 v3=0x918b028
(nil)
(nil)
0x918b008
(nil)
(nil)
(nil)
(nil)
0x918b008
(nil)
(nil)
0x918b008
(nil)
(nil)
(nil)
(nil)
Or, do I need to change shift_gear() function? Can I optimise it more while keeping the scalability-factor intact? Thanks in advance. If I want to put all these functions in C++ as Class Engine and Class Gearbox, can you show me a prototype?

You mention scaling to larger number of items, here is some parts that scale to 100,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct package_s
{
// ... other members data ...
struct package_s* next;
} package; //being lazy, I avoid typing struct everywhere...
#define HOWMANY (100)
package* v[HOWMANY];
#define MILES 15
int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3};
package*
journey(package* _current_frame, int _start, int _end)
{
int rpm = (_end > _start) ? (_end-_start) : (_start-_end);
if (rpm)
return engine_spin_at_gear(_current_frame, rpm);
else
return v[0];
}
package*
ignition_phase(int _batteryS, int _chargedL)
{
return journey(v[0], _batteryS, _chargedL);
}
And this fixes the addressing off the end of input_arr (maybe you want to wrap back to zero?)
void
transmit_in_order(int*input_arr)
{
package *v6;
int i;
for (i=0; i<MILES-2; i++) {
v6 = ignition_phase(input_arr[i], input_arr[i+1]);
printf("%p\n", v6);
}
}
And the main for configurable number of v[n],
int main()
{
int ndx;
for(ndx=0; ndx<HOWMANY; ++ndx)
{
v[ndx] = malloc(sizeof(package));
}
for(ndx=0; ndx<HOWMANY; ++ndx)
{
v[ndx]->next = v[(ndx+1)%HOWMANY];
printf("v[%d]=%p\t", ndx, v[ndx]);
}
printf("\n", ndx, v[ndx]);
transmit_in_order(input_arr);
return 0;
}

Optimization aside, you have a problem with input_arr:
int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3}; //has 15 elements
While following loop requires 16:
for (i=0; i<MILES-1; i++) { //[edited] so i goes from 0 to 13
v6 = ignition_phase(input_arr[i], input_arr[i+1]); //otherwise, i goes to 14, +1 == 15 - 1 too big
printf("%p\n", v6);
}
Either create a bigger array, or stop the loop 1 increment earlier.
Regarding this code:
struct package *engine_spin_at_gear(struct package *_init_cycle0, int countSession)
{
while (countSession--) {
shift_gear(_init_cycle0); // }
return deliver(base(_init_cycle0));
}
return NULL;
} //move this one to after shift_gear(_init_cycle0);
Should the closing while loop } be moved to where indicated at comment? (per your's and Charlie's observation) If you keep the return statement in there , you will never make it past the first loop.
Output changes according to minor changes to code:
After changing for for (i=0; i<MILES; i++) { to for (i=0; i<MILES-1; i++) {
After changing
while (countSession--) {
shift_gear(_init_cycle0);
return deliver(base(_init_cycle0));
}
to:
while (countSession--) {
shift_gear(_init_cycle0);}
return deliver(base(_init_cycle0));
// }
So, it appears there is some effect, but I am not sure how to interpret this output. i.e. what significance these changes mean.

Related

C++, Weird behavior of cout when trying to print integers

Im trying to write a class that stores an id and a value in an container class.
Im using an nested class as my data structure.
When im compiling the code sometimes it prints perfectly, sometimes it prints nothing and sometimes it prints half of the data then stops.
When i debug the code the same weird behavior occours, when it fails during debug it throws an error "Map.exe has triggered a breakpoint.", the Error occours in the print method when im using cout.
cmap.h
#pragma once
class CMap
{
public:
CMap();
~CMap();
CMap& Add(int id, int value);
void print() const;
private:
class container
{
public:
~container();
int container_id = 0;
int container_value = 0;
};
container* p_komp_;
int dim_ = -1;
void resize();
};
cmap.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
CMap::CMap()
{
p_komp_ = new container[0];
}
CMap::~CMap()
{
p_komp_ = nullptr;
cout << "destroy cmap";
}
CMap& CMap::Add(int id, int value)
{
resize();
p_komp_[dim_].container_id = id;
p_komp_[dim_].container_value = value;
return *this;
}
void CMap::resize()
{
container* temp_array = new container[++dim_];
if (dim_ == 0)
{
temp_array[0].container_id = p_komp_[0].container_id;
temp_array[0].container_value = p_komp_[0].container_value;
}
for (unsigned i = 0; i < dim_; i++)
{
temp_array[i].container_id = p_komp_[i].container_id;
temp_array[i].container_value = p_komp_[i].container_value;
}
p_komp_ = temp_array;
}
void CMap::print() const
{
for (unsigned i = 0; i <= dim_; i++)
{
cout << p_komp_[i].container_id;
cout << p_komp_[i].container_value;
}
}
CMap::container::~container()
{
cout << "destruct container";
}
Map.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
void main(void)
{
CMap m2;
m2.Add(1, 7);
m2.Add(3, 5);
m2.print();
}
These two things are a possible reason for your problem:
int dim_ = -1;
and
container* temp_array = new container[++dim_];
When you allocate, you increase dim_ from -1 to 0. That is you create a zero-sized "array", where every indexing into it will be out of bounds and lead to undefined behavior.
You also have memory leaks since you never delete[] what you new[]. I didn't look for more problems, but there probably a more.
And an "array" (created at compile-time or through new[]) will have indexes from 0 to size - 1 (inclusive). You seem to think that the "size" you provide is the top index. It's not, it's the number of elements.
It seems to me that you might need to take a few steps back, get a couple of good books to read, and almost start over.

c++ program crashes before main

When I run my code below, the program crashes and the compiler message is Segmentation fault. I've searched for bugs in my code but I can't find any. My program doesn't even seem to enter main(), because I've tried using 'cout' to see where it crashes but I get no output, even when 'cout'-ing immedeately after main starts. Here is the code. Can someone tell me what the problem is?
#include <cmath>
#include <stdio.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct edge_t
{
int a,b,w;
};
bool comp(edge_t a, edge_t b)
{
if(a.w < b.w)
return true;
return false;
}
vector<int> parent;
int find_parent(int x)
{
if(parent[x] == x)
return x;
parent[x] = find_parent(parent[x]);
return parent[x];
}
void join(int a,int b)
{
parent[find_parent(a)] = find_parent(b);
return;
}
int mst(vector<edge_t> v)
{
sort(v.begin() , v.end() , comp);
for(int i=0;i<v.size();++i)
parent[i] = i;
int sum = 0;
for(int i=0;i<v.size();++i)
{
if(find_parent(v[i].a) != find_parent(v[i].b))
{
join(v[i].a, v[i].b);
sum += v[i].w;
}
}
return sum;
}
int main() {
cout<<"Hello?\n"; ///does not display anything QQ
int n,m;
scanf("%d %d",&n,&m);
parent.resize(n);
int p,q,r;
vector<edge_t> edges;
int s =0;
for(int i=0;i<m;++i)
{
scanf("%d %d %d",&p,&q,&r);
edge_t tmp;
tmp.a = p;
tmp.b = q;
tmp.w = r;
s+=r;
edges.push_back(tmp);
}
printf("%d\n", s - mst(edges));
return 0;
}
I'm using the online ide on hackerrank.com (I'm practising problems there).
Inside your mst function
for (int i = 0; i<v.size(); ++i)
parent[i] = i;
This assumes that parent has the same or more elements that v, and if that's not the case, your program crashes.
In the same function, you are calling find_parent and you haven't verified that a & b are lower than parent.size(), which would be fine if you checked that in your find_parent function, but you don't check it there either.
if (find_parent(v[i].a) != find_parent(v[i].b))
{
join(v[i].a, v[i].b);
sum += v[i].w;
}
Therefore, if find_parent gets invalid input, your program crashes
int find_parent(int x)
{
if (parent[x] == x)
return x;
}
Depending on your compilation environment if you have an instruction set enabled that your system does not support (e.g. AVX) crashes can occur prior to main (I have seen this happen on Windows with VC++). Try compiling with all optimisations switched off, for an "ancient" target architecture.
Depending on your platform, this could also be due to shared libraries not being found, although this seems less likely.
EDIT: Deleted the bit about cout since you have a end line character and main. That was an off thought.

'future' has been explicitly marked deleted here

I am trying to build a Async application to allow processing of large lists in parallel, and after two days of learning C++ through googling I have come up with the title error, from the following code:
//
// main.cpp
// ThreadedLearning
//
// Created by Andy Kirk on 19/01/2016.
// Copyright © 2016 Andy Kirk. All rights reserved.
//
#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
#include <future>
typedef struct {
long mailing_id;
char emailAddress[100];
} emailStruct ;
typedef struct {
long mailing_id = 0;
int result = 0;
} returnValues;
returnValues work(emailStruct eMail) {
returnValues result;
std::this_thread::sleep_for(std::chrono::seconds(2));
result.mailing_id = eMail.mailing_id;
return result;
}
int main(int argc, const char * argv[]) {
std::vector<emailStruct> Emails;
emailStruct eMail;
// Create a Dummy Structure Vector
for (int i = 0 ; i < 100 ; ++i) {
std::snprintf(eMail.emailAddress,sizeof(eMail.emailAddress),"user-%d#email_domain.tld",i);
eMail.mailing_id = i;
Emails.push_back(eMail);
}
std::vector<std::future<returnValues>> workers;
int worker_count = 0;
int max_workers = 11;
for ( ; worker_count < Emails.size(); worker_count += max_workers ){
workers.clear();
for (int inner_count = 0 ; inner_count < max_workers ; ++inner_count) {
int entry = worker_count + inner_count;
if(entry < Emails.size()) {
emailStruct workItem = Emails[entry];
auto fut = std::async(&work, workItem);
workers.push_back(fut);
}
}
std::for_each(workers.begin(), workers.end(), [](std::future<returnValues> & res) {
res.get();
});
}
return 0;
}
Really not sure what I am doing wrong, and have found limited answers searching. Its on OSX 10 if that is relevant, and XCode 7.
The future class has its copy constructor deleted, because you really don't want to have multiple copies of it.
To add it to the vector, you have to move it instead of copying it:
workers.push_back(std::move(fut));
This error can also be raised if you are passing a future object (within a thread) to a function which expects a pass by value.
For example, this would raise an error when you pass the future:
void multiplyForever(int x, int y, std::future<void> exit_future);
multiplyForever(3, 5, fut);
You can fix it by passing the future by reference:
void multiplyForever(int x, int y, std::future<void>& exit_future);
multiplyForever(3, 5, fut);

pointer being freed was not allocated error?

I have seen many posts for this error. But I'm not reserving memory dynamically or doing anything in destructor:
This program is SSJF algorithm for selecting cylinder in operating system.
I have a simple class called IO:
class IO
{
public:
IO();
IO(int,int);
void setIO(int,int);
~IO();
int trackNo;
int arrival;
int start;
int end;
bool finished;
};
Here is the implementation of the class::
IO::IO(int arr, int tNum)
{
this->arrival = arr;
this->trackNo = tNum;
this->start = 0;
this->end = 0;
}
IO::IO()
{
}
IO::~IO()
{
}
void IO::setIO(int t1, int t2)
{
this->trackNo = t1;
this->arrival = t2;
}
And finally here is part of main program:
list<IO> myList;
....
myList.push_back(tmpIO); //Add to the list
...
list<IO> wt_list;
And later I'm trying to do some operations. I have deleted some of the part which is not related.
//list<IO>::iterator itMin;
while(myList.size()>0)
{
//If it is the first input just get it
if(f)
{
IO selected = myList.front();
curr_time += selected.arrival + selected.trackNo;
f=false;
cout << selected.arrival<<endl;
lastPos = selected.trackNo;
myList.pop_front();
}
//Check if there is any item to add to queue
while(myList.front().arrival < curr_time)
{
wt_list.push_back(myList.front());
myList.pop_front(); //Error is coming from this line
}
while(wt_list.size()>0)
{
}
Error message:
malloc: * error for object 0x10f68b3e0: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
Anyone can help me and explain why I get this error and how can I skip it?
The simplest code I can come up with to reproduce this error looks like this:
#include <list>
int main()
{
std::list<int> mylist;
mylist.pop_front();
}
I can prevent the error by doing:
#include <list>
int main()
{
std::list<int> mylist;
if (!mylist.empty())
{
mylist.pop_front();
}
}
You're calling:
myList.pop_front();
...within a while-loop, which in turn is within a while-loop that also calls myList.pop_front().
I can only suggest that you debug your code to see how many times pop_front() is invoked for mylist. My money is on it being more than mylist.size() times, hence my question in the comments (with new emphasis):
How many items are in myList when the error is thrown?
Perhaps the simplest fix will be to replace...
//Check if there is any item to add to queue
while(myList.front().arrival < curr_time)
{
wt_list.push_back(myList.front());
myList.pop_front(); //Error is coming from this line
}
while(wt_list.size()>0)
{
}
...with...
while (!mylist.empty() && myList.front().arrival < curr_time)
{
wt_list.push_back(myList.front());
myList.pop_front();
}
while (!wt_list.empty())
{
}
...but it's hard to tell from the snippet you've provided.

How can I prevent segmentation faults in my program?

I have a C assignment. It is a lot longer than the code shown below, and we are given the function prototypes and instructions only. I have done my best at writing code, but I am stuck with segmentation faults. When I compile and run the program below on Linux, at "735 NaN" it will terminate, indicating a segfault occurred. Why? What am I doing wrong? Basically, the program does not let me access table->list_array[735]->value and table->list_array[735]->key. This is of course the first segfault. There might be more following index 735.
#include <stdio.h>
#include <stdlib.h>
typedef struct list_node list_node_t;
struct list_node
{
char *key;
int value;
list_node_t *next;
};
typedef struct count_table count_table_t;
struct count_table {
int size;
list_node_t **list_array;
};
count_table_t* table_allocate(int size)
{
count_table_t *ptr = malloc(sizeof(count_table_t));
ptr->size = size;
list_node_t *nodes[size];
int k;
for(k=0; k<size; k++){
nodes[k] = NULL;
}
ptr->list_array = nodes;
return ptr;
}
void table_addvalue(count_table_t *table)
{
int i;
for(i=0; i<table->size; i++)
{
table->list_array[i] = malloc(sizeof(list_node_t));
table->list_array[i]->value = i;
table->list_array[i]->key = "NaN";
table->list_array[i]->next = NULL;
}
}
int main()
{
count_table_t *table = table_allocate(1000);
table_addvalue(table);
int i;
for(i=0; i<table->size; i++)
printf("%d %s\n", table->list_array[i]->value, table->list_array[i]->key);
return 0;
}
You're point ptr->list_array at a local variable (nodes) in table_allocate, which goes away when that function returns, leaving a dangling pointer. You probably want
list_node_t **nodes = malloc(size * sizeof(list_node_t *));
I recommend the routine use of valgrind(1) to prevent such problems from occurring.