I am working on worm_sim simulater , ubuntu, gcc, codeblocks IDE
traffic_source.h file
class Traffic_source : public Buffer_owner, public Connector, public Addressee{
private:
static unsigned int id_base;
unsigned int id;
unsigned int packet_size;
unsigned int flit_size;
double packet_generating_rate;
int pkt_id;
traffic_source_state ts_state;
double* packet_to_destination_rate;
Traffic_mode traffic_mode;
int period; // period for packet generation using trace_file
ifstream trace_file;
int trace_file_loop_cnt; // how many times we have gone over the trace file so far
bool trace_file_empty;
ofstream trace_dump; // trace file to dump out
typedef struct Message {
int timestamp;
unsigned int destination;
unsigned int size;
} Message, *pMessage;
Message pre_fetched_message;
bool get_next_message(Message & msg);
unsigned int get_destination_uniform(void) const;
unsigned int get_destination_transpose1(void) const;
unsigned int get_destination_transpose2(void) const;
unsigned int get_destination_hotspot(void) const;
unsigned int get_destination_customized(void) const;
void generate_a_packet(unsigned int dst_id);
void generate_packets(const Message & rec);
public:
Traffic_source(Position p, int buf_sz);
~Traffic_source();
bool can_send(void) const;
bool can_receive(void) const { return false; }
bool send(void);
bool receive(class Flit * a_flit) { return false; }
class Connector * get_receiver(void) const;
static void reset_id_base(void) { id_base = 0; }
void tick(void);
/* traffic control routines */
void set_packet_generating_rate(double r);
void set_packet_to_destination_rate(unsigned int dst_id, double rate);
double get_packet_to_destination_rate(unsigned int dst_id) const;
double get_total_packet_injection_rate(void) const;
int set_trace_file(char * file_name);
bool has_trace_file(void) { return (trace_file.is_open()); }
int get_id(void) const { return id; }
};
traffic_source.cpp
Traffic_source::Traffic_source(Position p, int buf_sz) : Buffer_owner(buf_sz), Addressee(p) {
id = id_base ++;
packet_generating_rate = param.packet_generating_rate;
packet_size = param.flits_per_packet;
flit_size = param.flit_size;
traffic_mode = param.traffic_mode;
period = 0;
packet_to_destination_rate = 0;
pkt_id = 0;
ts_state = OFF_
if (param.dump_traffic_source_trace) {
char file_name[20];
sprintf(file_name, "%d.trace", id);
trace_dump.open(file_name);
if (!trace_dump.is_open() || !trace_dump.good()) {
cerr << "Error in opening file " << file_name << " for trace dumping" << endl;
exit(-1);
}
trace_dump << "PERIODt" << param.simulation_length << endl;
trace_dump << "#Trace file dumped by worm_sim from node " << id << endl;
trace_dump << "#Folloing lines are with format as:" << endl
<< "#timestampt" << "destinationt" << "message_size(bits):" << endl;
}
}
bool Traffic_source::can_send(void) const
{
int router_id=get_id();
unsigned int local_availability;
pRouter a_router= param.network->get_router(router_id);
local_availability=a_router->get_port_availability(0);
//cout<<local_availability<<endl;
if (buffer.is_empty())
return false;
if(local_availability <= 0)
{
packet_generating_rate = 0; //error: assignment of member ‘Traffic_source::packet_generating_rate’ in read-only object|
set_packet_generating_rate(0); // error: passing ‘const Traffic_source’ as ‘this’ argument of ‘void Traffic_source::set_packet_generating_rate(double)’ discards qualifiers [-fpermissive]|
return false;
}
// This is somehow trick, we need to verify whether the first flit in the fifo
// is received right in this clock cycle. If so, we can not send it
const Flit * first_flit = buffer.peek_flit();
if (first_flit->arrived_in_this_cycle())
return false;
pConnector receiver = get_receiver();
if (receiver)
return receiver->can_receive();
else
return false;
}
the value packet_generating_rate is not const but when i try to modify it either directly or using the set function it give me errors
packet_generating_rate = 0; //error: assignment of member
‘Traffic_source::packet_generating_rate’ in read-only object|
set_packet_generating_rate(0); // error: passing ‘const Traffic_source’ as ‘this’ argument of ‘void Traffic_source::set_packet_generating_rate(double)’ discards qualifiers [-fpermissive]|
although it is used on other files with no problem, any suggestion plz
IDEONE: http://ideone.com/uSqSq7
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
struct node
{
int value, position;
bool left, right;
bool operator < (const node& a) const
{
return value < a.value;
}
};
int main()
{
int n;
cin >> n;
vector < node > a(n);
set < node > s;
for (auto &i: a)
{
cin >> i.value;
i.left=i.right=0;
}
a[0].position=1;
s.insert(a[0]);
for (int i=1; i<n; i++)
{
auto it=s.upper_bound(a[i]);
auto it2=it; --it2;
if (it==s.begin())
{
a[i].position=2*it->position;
s.insert(a[i]);
it->left=1;
}
else if (it==s.end())
{
a[i].position=2*(--it)->position+1;
s.insert(a[i]);
it->right=1;
}
else
{
if (it2->right==0)
{
a[i].position=2*it2->position+1;
s.insert(a[i]);
it2->right=1;
}
else
{
a[i].position=2*it->position;
s.insert(a[i]);
it->left=1;
}
}
}
for (auto i: a) cout << i.position << ' ';
}
When I compile this code, I get
error: assignment of member ‘node::right’ in read-only object
I think this has something to do with the const
in bool operator <
, but I cannot get rid of it as it is necessary to create the set.
hanshenrik
18.9k3 gold badges41 silver badges82 bronze badges
asked Feb 10, 2016 at 12:30
7
Angelika Langer once wrote a piece about this: Are Set Iterators Mutable or Immutable?.
You can solve this by defining the Node
members immaterial for the set
ordering as mutable
:
mutable bool left, right;
(see a building version in ideone.)
Personally, I would consider a design mapping the immutable part to mutable parts using a map
.
anukul
1,9011 gold badge19 silver badges36 bronze badges
answered Feb 10, 2016 at 12:50
Ami TavoryAmi Tavory
73.3k10 gold badges138 silver badges178 bronze badges
0
Problem:
Remember that keys in a std::set are constant. You can’t change a key after it’s inserted into the set. So when you dereference the iterator, it necessarily returns a constant reference.
const node& n = (*it);
n->left = 1; //It will not allow you to change as n is const &.
Solution:
As Ami Tavory answered, you can declare left and right as mutable.
answered Feb 10, 2016 at 13:32
tohtarov_ufa 0 / 0 / 0 Регистрация: 13.01.2015 Сообщений: 137 |
||||||||
1 |
||||||||
01.06.2015, 06:58. Показов 3130. Ответов 4 Метки нет (Все метки)
Добрый день!
функция в .cpp файле
Почему то выдает ошибку что для меня лично не понятно Спасибо за помощь!
__________________
0 |
1442 / 1323 / 131 Регистрация: 20.03.2009 Сообщений: 4,689 Записей в блоге: 11 |
|
01.06.2015, 07:52 |
2 |
не зная броду, не суйся в воду
0 |
0 / 0 / 0 Регистрация: 13.01.2015 Сообщений: 137 |
|
01.06.2015, 11:57 [ТС] |
3 |
для того, что это переопределенная функция и без const она вообще не отрабатывает.
0 |
1442 / 1323 / 131 Регистрация: 20.03.2009 Сообщений: 4,689 Записей в блоге: 11 |
|
01.06.2015, 17:37 |
4 |
0 |
Псевдослучайный 1946 / 1145 / 98 Регистрация: 13.09.2011 Сообщений: 3,215 |
|
01.06.2015, 18:00 |
5 |
Сообщение было отмечено tohtarov_ufa как решение Решение
для того, что это переопределенная функция и без const она вообще не отрабатывает. Ну ещё бы, ведь это будет уже совсем другой метод, а не перегрузка нужного.
1 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
01.06.2015, 18:00 |
5 |
IDEONE: http://ideone.com/uSqSq7
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
struct node
{
int value, position;
bool left, right;
bool operator < (const node& a) const
{
return value < a.value;
}
};
int main()
{
int n;
cin >> n;
vector < node > a(n);
set < node > s;
for (auto &i: a)
{
cin >> i.value;
i.left=i.right=0;
}
a[0].position=1;
s.insert(a[0]);
for (int i=1; i<n; i++)
{
auto it=s.upper_bound(a[i]);
auto it2=it; --it2;
if (it==s.begin())
{
a[i].position=2*it->position;
s.insert(a[i]);
it->left=1;
}
else if (it==s.end())
{
a[i].position=2*(--it)->position+1;
s.insert(a[i]);
it->right=1;
}
else
{
if (it2->right==0)
{
a[i].position=2*it2->position+1;
s.insert(a[i]);
it2->right=1;
}
else
{
a[i].position=2*it->position;
s.insert(a[i]);
it->left=1;
}
}
}
for (auto i: a) cout << i.position << ' ';
}
Когда я компилирую этот код, я получаю
error: assignment of member ‘node::right’ in read-only object
Я думаю, что это как-то связано с const
в bool operator <
, но я не могу от этого избавиться, так как нужно создавать набор.
2
Решение
Другие решения
Проблема:
Помните, что ключи в std :: set являются постоянными. Вы не можете изменить ключ после того, как он вставлен в набор. Поэтому, когда вы разыменовываете итератор, он обязательно возвращает постоянную ссылку.
const node& n = (*it);
n->left = 1; //It will not allow you to change as n is const &.
Решение:
Как ответила Ами Тавори, вы можете объявить левую и правую изменяемыми.
0
-
07-17-2020
#1
Registered User
Error: assignment of i_value in read-only object
Hello,
I have two programs that to the best of my knowledge use the same data structures and contain the same statements.
One program works and the other fails with the error in the title. No doubt there is a reason, but at this stage it is not clear to me.
Please refer to the two attachments:
- Example_Data_Structure
- Linked_List_Example
Example_Data_Structure is a short program that builds and executes as I would expect.
Example_Data_Structure contains an extract of code from Linked_List_Example.
For some reason the code works fine in isolation, but not when combined with the other statements.
It’s a mystery to me.
Linked_List_Example, contains a lot more code (sorry), but also contains the same code as in Example_Data_Structure. I’ve had to include the whole program because obviously there is something in it which causes the following statement to fail.
Code:
record->i_value = 100;
For reason;
Code:
162|error: assignment of member �i_value� in read-only object|
For some reason I can’t upload the other program. No errors but it doesn’t appear in the Attachment Manager.
Also the Attachment Manager states that uploaded programs are supposedly deleted after 1 hour; but my upload from yesterday is still there?
-
07-17-2020
#2
Registered User
I don’t have access to Attachments in ‘My Settings’ ?
-
07-17-2020
#3
and the hat of int overfl
Example_Data_Structure.c seems fine to me.
Code:
$ gcc -Wall Example_Data_Structure.c $ ./a.out Record - detail: some string Record - value: 100
-
07-17-2020
#4
Registered User
Originally Posted by Salem
It seems fine to me.
Yes it is, the issue is that the same code in the other example doesn’t work.
I’m assuming that the issue must be due to some of the other statements I have in the 2nd program; it is not at all clear to me why the error is occurring.
So I need to upload the other example so that I can get an informed opinion.
The attachment manager seems buggy to me. It always seems to take multiple attempts to get an attachment to upload / appear; and I’ve not managed to upload the 2nd program at all??
-
07-17-2020
#5
Registered User
Finally managed to upload the 2nd attachment
-
07-17-2020
#6
and the hat of int overfl
Well the big problem is you’re missing a brace at the end of the else in add_record()
Then
Code:
foo.c: In function �add_key�: foo.c:54:22: warning: assignment discards �const� qualifier from pointer target type [-Wdiscarded-qualifiers] current->key = key; ^ foo.c:73:28: warning: assignment discards �const� qualifier from pointer target type [-Wdiscarded-qualifiers] current->next->key = key; ^
Use strcpy to copy things.
Code:
foo.c: In function �add_record�: foo.c:89:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses] if (current->record_list = NULL) { ^ foo.c:121:13: warning: suggest parentheses around assignment used as truth value [-Wparentheses] if (current->record_list = NULL) { ^
You probably meant to use ==
There’s no reason to cast the return result of malloc.
> record_list =(record_t *) malloc(sizeof(record_t));
Casting malloc — Cprogramming.com
-
07-17-2020
#7
Registered User
Originally Posted by Salem
There’s no reason to cast the return result of malloc.
> record_list = (record_t *) malloc(sizeof(record_t));
Casting malloc — Cprogramming.comAppreciate your reply, I must admit I have been programming on my laptop and with the smaller screen I was having trouble seeing the whole function. I should have used the «-» minus key to condense the code blocks to make sure that I had all the brackets matched up.
I’m afraid I don’t understand your last comment regarding casting malloc.
Unfortunately I’m none the wiser, even after reading the included link.
My understanding is that each time I add a new «record» in the list. I need to allocate memory for that record.
And the statement
Code:
record_list= (record_t*) ...
is the statement required to allocate the memory for the next record/structure in the list, before then populating the fields in the record.
Can you show the statement that I should be using instead?
-
07-18-2020
#8
and the hat of int overfl
I mean you should be able to do this without upsetting the compiler.
Code:
record_list = malloc(sizeof(record_t));
The cast would cover up the mistake of not including stdlib.h
If you get a message along the lines of ‘cannot convert void* to type*’, then that means you’re using C++ to compile your C program.
This is something you shouldn’t be doing either.
-
07-18-2020
#9
Registered User
Originally Posted by Salem
The cast would cover up the mistake of not including stdlib.h
If you get a message along the lines of ‘cannot convert void* to type*’, then that means you’re using C++ to compile your C program.
This is something you shouldn’t be doing either.The includes that are specified are:
Code:
#include <stdio.h> #include <stdlib.h> #include <string.h>
The compile options that I’m using are:
Code:
-------------- Build: Debug in Linked_List_example_with_Data_Structure_II (compiler: GNU GCC Compiler)--------------- gcc -Wall -g -c /home/dev/c/learn/Linked_List_example_with_Data_Structure_II/main.c -o obj/Debug/main.o gcc -o bin/Debug/Linked_List_example_with_Data_Structure_II obj/Debug/main.o Output file is bin/Debug/Linked_List_example_with_Data_Structure_II with size 10.74 KB Process terminated with status 0 (0 minute(s), 0 second(s)) 0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
-
07-18-2020
#10
Registered User
There is still an error in the add_record function.
Using the debugger I observe that the execution crashes at line 96
Code:
strcpy(current->record_list->c_detail1,record->c_detail1);
Unfortunately this statement looks correct to me.
I’ve used printf at line 92 & 93 to confirm that the record details (i.e. the «inputs» are correctly set.
Perhaps the issue is with line 95,
Code:
record_list = (record_t *) malloc(sizeof(record_t));
although I don’t observe any errors when this line is executed
PS: I had issues uploading the attachment again. Does anybody else have issues with this. I’m using latest version of Chrome on Windows
-
07-18-2020
#11
misoturbutc
Originally Posted by VeeDub
Code:
strcpy(current->record_list->c_detail1,record->c_detail1);
current->record_list is NULL on line 96, as proven by line 89, and then you’re trying to dereference (i.e. you’re effectively trying to do NULL->c_detail1) so it crashes.
On line 95, where is record_list even declared? Same for line 109… does this compile? Edit: nvm, I see now that it’s a global that is somewhat hidden because it’s indented badly. Why is it global?
-
07-18-2020
#12
Registered User
Originally Posted by Hodor
current->record_list is NULL on line 96, as proven by line 89, and then you’re trying to dereference (i.e. you’re effectively trying to do NULL->c_detail1) so it crashes.
On line 95, where is record_list even declared? Same for line 109… does this compile? Edit: nvm, I see now that it’s a global that is somewhat hidden because it’s indented badly. Why is it global?
Hello Hodor,
My understanding is that line 95
Code:
record_list = (record_t *) malloc(sizeof(record_t));
Allocates memory for a new record, which I then update in lines 96, 97 and 98.
If I comment line 96
Code:
strcpy(current->record_list->c_detail1,record->c_detail1);
Then line 97 fails
Code:
current->record_list->i_value = record->i_value;
So the issue must be in line 95
Code:
record_list = (record_t *) malloc(sizeof(record_t));
But a similar statement works earlier in the code (line 161) to create a record structure
Code:
record = (record_t *) malloc(sizeof(record_t));
and I successfully update this record in main(); so I don’t understand why line 95 isn’t working.
As to why the record structure is a global variable. My intention is to access and update the record structure in a number of functions — not just add_record.
-
07-18-2020
#13
misoturbutc
When your code reaches line 96, what is the value of current->record_list? As far as I can see it’s NULL, because program execution only reaches line 96 if current->record_list is NULL (see line 89; i.e. it’s still NULL when line 96 is reached). You can’t do
Code:
strcpy(current->record_list->c_detail1,record->c_detail1);
Because the part in bold must be NULL otherwise the line would never have been reached because execution only reaches line 96 if the part in bold is NULL (because of line 89).
Maybe before reaching line 96, and after line 89, you have to do something like
Code:
current->record_list = record_list;
(But don’t quote me on that I haven’t looked very closely at your code because I’m on a device that makes it difficult for me. That said you have to either add something like the line above or change lines 96-98 to use record_list rather than current->record_list or something else that is not NULL)
Edit: What I’m suggesting is either :
Code:
/* Check head of record list */ if (current->record_list == NULL) { /* First record */ // printf("Record - detail: %sn",record->c_detail1); // printf("Record - value: %dn",record->i_value); record_list = (record_t *) malloc(sizeof(record_t)); current->record_list = record_list; strcpy(current->record_list->c_detail1,record->c_detail1); current->record_list->i_value = record->i_value; current->record_list->next = NULL; } /* current->record_list == NULL */
or
Code:
/* Check head of record list */ if (current->record_list == NULL) { /* First record */ // printf("Record - detail: %sn",record->c_detail1); // printf("Record - value: %dn",record->i_value); record_list = (record_t *) malloc(sizeof(record_t)); strcpy(record_list->c_detail1,record->c_detail1); record_list->i_value = record->i_value; record_list->next = NULL; }
Last edited by Hodor; 07-18-2020 at 10:14 PM.
-
07-18-2020
#14
Registered User
Thanks Hodor,
You’re right of course
Line 95 should have been
Code:
current->record_list = (record_t *) malloc(sizeof(record_t));
If I keep making enough mistakes I’ll eventually start to learn.
I just need to get to the point where I can fix them by myself.
Cheers
-
07-18-2020
#15
misoturbutc
Originally Posted by VeeDub
Thanks Hodor,
You’re right of course
Line 95 should have been
Code:
current->record_list = (record_t *) malloc(sizeof(record_t));
If I keep making enough mistakes I’ll eventually start to learn.
I just need to get to the point where I can fix them by myself.
Cheers
I made an edit while you were replying. Your way in this new post is fine as well, of course
Comments
UralZima
referenced
this issue
Sep 27, 2018
When zfs_kobj_init() is called with an attr_cnt of 0 only the
kobj->zko_default_attrs is allocated. It subsequently won't
get freed in zfs_kobj_release since the free is wrapped in
a kobj->zko_attr_count != 0 conditional.
Split the block in zfs_kobj_release() to make sure the
kobj->zko_default_attrs are freed in this case.
Additionally, fix a minor spelling mistake and typo in
zfs_kobj_init() which could also cause a leak but in practice
is almost certain not to fail.
Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed-by: Tim Chase <tim@chase2k.com>
Reviewed-by: John Gallagher <john.gallagher@delphix.com>
Reviewed-by: Don Brady <don.brady@delphix.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #7957
openzfs
locked as too heated and limited conversation to collaborators
Jan 28, 2019
bool Traffic_source::can_send(void) const
Как уже указывали другие, проблема в том, что внутри const
функция (последняя const
в строке) вы не можете изменять элементы объекта. Фактически функция-член преобразуется во что-то похожее на: bool Traffic_source__can_send( const Traffic_source* this, void )
, там this
аргумент является указателем на const
. Что в свою очередь означает, что packet_generating_rate
is const
в контексте функции.
Есть три альтернативы, которым вы можете следовать здесь:
- не изменять член
- не отмечайте функцию
const
- сделать
packet_generating_rate
mutable
Первые два варианта являются общими: либо функция const
и не изменяет объект, или он не const
и может изменять объект. Однако бывают случаи, когда вы хотеть для изменения члена в const
указатель члена. В этом случае вы можете пометить объявление члена как mutable
чтобы разрешить модификацию внутри const
функции-члены.
Обратите внимание, однако, что обычно это делается, когда переменная-член не участвует в видимый состояние объекта. Например mutex
переменная не изменяет значение, возвращаемое геттером, или состояние объекта впоследствии, но геттерам необходимо блокировать (модифицировать) объект, чтобы получить согласованное представление объекта в многопоточных средах. Второй типичный пример — кэш, где объект может предлагать операцию, которую сложно вычислить, поэтому функция, выполняющая эту операцию, может кэш результат на потом. Опять же, независимо от того, пересчитывается ли значение или извлекается из кэш это будет то же самое, поэтому видимое состояние объекта не изменится. Наконец, иногда вам может понадобиться злоупотребить конструкцией, чтобы соответствовать существующему интерфейсу.
Теперь вам решать, какой из трех вариантов применить к вашему дизайну. Если вам нужно изменить атрибут члена, то либо член является частью видимого состояния, и функция не должна быть const
, либо оно не является частью состояния объекта и может быть помечено mutable
.