Đoạn code bị ma nhập giữa ban ngày :((

Mình có class như sau:

class CameraSetting{
public:
    int index=0;
    double exposure=0;
    double brightness=0;
    double saturation=0;
    double gamma=0;
    double contrast=0;
    double gain=0;
    int energyTime=0;
}

Sau khi chạy đoạn lệnh sau:

CameraSetting setting=....
CameraSetting newSetting=...
memcpy(&setting, &newSetting, sizeof(CameraSetting);
MesageBoxA(nullptr, std::to_string(setting.contrast).c_str(),"",0);
MesageBoxA(nullptr, std::to_string(setting.contrast).c_str(),"",0);

Kết quả là 2 dòng cuối cho kết quả lần lượt :
159.
128.
Mặc dù 2 dòng này giống hệt nhau (copy mà).
Ứng dụng đơn luồng, Message::show truyền tham trị. Clear/ build nhiều lần.

Chuyện gì đang xảy ra và tôi là ai @@.

thế này là bạn đang coppy từ thằng new Setting qua thằng setting đó

Đúng mình copy từ thằng newSetting sang setting.

Nhưng điểm khó hiểu là thằng setting.contrast (và cả những thằng setting.* khác) tại sao lại có 2 giá trị khác nhau giữa 2 lệnh liên tiếp.

2 lệnh MessageBoxA liên tiếp và hoàn toàn giống nhau nhưng lại show ra 2 message khác nhau.

Mình có dùng memcpy để kiểm tra setting và newSetting có giống nhau không thì lần đầu trả về 0( giống) nhưng lần liên tiếp ngay sau đó trả về -1 và setting bị thay đổi giá trị.

3 Likes

mình k biết contrast này là system function hay funtion do bạn viết ra
k biết là hàm đó có tác dụng gì. :joy:

Nó là 1 field trong class CameraSetting mình viết trên đầu bài đó.

3 Likes

à à hiểu rồi hahaah, đi ăn cơm đã ông ơi

.c_str() trả về 1 con trỏ trỏ tới chuỗi to_string kia, mà chuỗi đó là giá trị tạm thời: sau khi tạo ra và gọi .c_str() sẽ bị hủy. Lúc này con trỏ c_str trỏ tới giá trị đã bị xóa => undefined behavior. Cần lưu chuỗi to_string đó ở đâu đó :V tồn tại lâu hơn hoặc lâu bằng cái messagebox kia :V

ví dụ dòng trên viết thành 2 dòng :V

auto contrastStr = std::to_string(setting.contrast);
MesageBoxA(nullptr, contrastStr.c_str(), "", 0);
3 Likes

Vấn đề ở chỗ thế này :

string s1 = std::to_string(setting.contrast);
string s2 = std::to_string(setting.contrast);

2 dòng liên tiếp giống hệt nhau cho ra s1 và s2 khác nhau.
Kiểm tra thêm bằng memcpy 2 lần liên tiếp thì phát hiện setting bị thay đổi tại thời điểm giữa 2 lần mà không rõ nguyên nhân ::((
setting.contrast là 1 số double.

2 Likes

Lỡ dùng memcpy rồi thì dùng sprintf chớ :smiley:

2 Likes

update: mình bị nhầm lẫn về việc hiểu thị địa chỉ con trỏ
Tuy nhiên nên update thêm code để có thể dễ dàng điều tra hơn

Ko cần show off với lão Hạc đâu bạn, bản chất cái vd bạn đưa ra khác hoàn toàn situation của Lão Hạc, bạn đi cấp phát mới memoryzone thì tất nhiên cho dù cùng dùng chung 1 biến vẫn trỏ đến 2 address khác nhau. Cái @Duong_Act bị là

object x;
string a =  x.name
string b = x.name

Và a != b, đây mới là cái @Duong_Act đang bị.

3 Likes

Up hết lên git cho mọi người lấy về chơi thử được ko bạn?

2 Likes

Trong này mình thấy có 2 vấn đề:

  1. std::to_string(setting.contrast).c_str() như bạn @tntxtnt đã nói
  2. Chỗ memcpy, không biết class CameraSetting là chính xác như vậy chưa hay còn thêm các method khác? Nếu còn, có thể bởi vì nó không phải trivial copyable nên không thể dùng memcpy mà nên dùng copy constructor. Bạn có thể kiểm tra bằng cách static_assert(std::is_trivially_copyable_v<CameraSetting>);
2 Likes

Copy memory sao lại dùng printf hả bạn.

Project của công ty nên không up được nhé :slight_smile:

Ngay sau lệnh memcpy thì mình kiểm tra 2 cái setting và newSetting là hoàn toàn giống nhau. Bằng cách sử dụng memcmp thì trả về 0.

Nhưng dùng thêm một lần memcmp nữa thì nó return -1. Tức là dữ liệu của setting đột nhiên thay đổi tại thời điểm giữa 2 lần memcmp liên tiếp mà không rõ nguyên nhân gì.

Xin lỗi toàn thể bà con.
Là do mình bị ma nhập nhé. Có 1 con timer chưa tắt. ::((

3 Likes

Làm mình hóng :crazy_face::crazy_face:

2 Likes

nếu class ko có cấp phát động gì thì cứ xài a = b cho lành, tội gì memcpy cho mất công :V

nếu class mà thuộc tính để public như thế, lại thích xài memcpy thay cho operator= thì xài struct thay vì class cho nó “giống” C, class này chỉ hold data chứ ko làm gì hết :V

4 Likes

Kiến thức kém + thích nguy hiểm nó vậy đó người anh em ::))

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?