cuốn sách gpt4 ai đã làm

Truy cập dữ liệu từ bộ đệm được tạo bởi boost

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-03 07:02:13 29 4
mua khóa gpt4 Nike

Tôi đang cố gắng truy cập dữ liệu được tuần tự hóa bằng cách sử dụng các hàm đệm tăng cường và muốn đưa nó vào hai vectơ. Tôi gặp sự cố khi điền địa chỉ của vectơ thứ hai. Lớp sau đây hiển thị hai vectơ này và cách chúng được lấp đầy.

lớp LidarMeasurement {
private:
std::vector _header;
std::vector _azimuth;

public:

// Tiêu đề bao gồm một mảng uint32_t theo bố cục sau
Chỉ số enum : size_t {
góc ngang,
Đếm kênh,
KÍCH CỠ
};

rõ ràng LidarMeasurement(uint32_t NumOfChannels = 0u): _header(Index::SIZE + NumOfChannels, 0u) {
_header[Index::ChannelCount] = NumOfChannels;
}

// được gọi trước khi điền vectơ
đặt lại void(uint32_t Total_point_count) {
std::memset(_header.data() + Index::SIZE, 0, sizeof(uint32_t) * GetChannelCount());
_azimuth.clear();
_azimuth.reserve(tổng_điểm_count);
}

// sau khi đặt lại, hàm ghi điểm bắt đầu điền vectơ.. hàm sau được gọi 104 lần (không phải hằng số) trước khi đặt lại tiếp theo
void WritePoint(kênh uint32_t, float góc_hor) {
_header[Index::SIZE + kênh] += 1u;
_azimuth.emplace_back(angle_hor);
}

uint32_t GetChannelCount() const {
return _header[Index::ChannelCount];
}
}

Sau khi chúng được lấp đầy, nó sẽ được tuần tự hóa và gửi cho khách hàng. Nó được tuần tự hóa bằng các chức năng sau:

mẫu 
bộ đệm nội tuyến LidarSerializer::Serialize(
const Cảm biến&,
const LidarĐo lường & đo lường,
Bộ đệm &&đầu ra) {
std::array seq = {
boost::asio::buffer(measurement._header),
boost::asio::buffer(measurement._azimuth)};
đầu ra.copy_from(seq);
trả về std::move(output);
}

Sau khi nhận được dữ liệu được tuần tự hóa, tôi cần đặt góc phương vị trở lại vectơ. Tôi đang sử dụng hàm sau để lấy vector. _bắt đầu là địa chỉ của bộ đệm.

std::vector GetAzimuth(const uint32_t* _begin) const{
std::vector localAzimuthMemCopy;
Begin_azi = const_cast(reinterpret_cast(_begin )) + (sizeof(uint32_t) * (GetChannelCount() + Index::SIZE));
end_azi = Begin_azi + GetTotalPointCount();//Tổng số điểm là phép cộng của số điểm kênh riêng lẻ (không hiển thị ở đây)
for(float* i = Begin_azi; i < end_azi; i++){
localAzimuthMemCopy.emplace_back(*i);
}
trả về localAzimuthMemCopy;
}

Tuy nhiên, kết quả tôi nhận được có phần bù bộ nhớ. Tôi nhận được 104 giá trị, nhưng 18 giá trị cuối cùng là rác. Đọc vectơ từ địa chỉ bắt đầu sai. Có gì sai với mã này?

nhập mô tả hình ảnh ở đây

câu trả lời hay nhất

Sự cố xảy ra do lỗi tính toán địa chỉ bắt đầu.

Begin_azi = const_cast(reinterpret_cast(_begin )) + (sizeof(uint32_t) * (GetChannelCount() + Index::SIZE));

1) Số học con trỏ chỉ yêu cầu con trỏ và số phần tử di chuyển về phía trước. Số byte mà trình biên dịch sẽ tự khấu trừ dựa trên loại con trỏ. Vậy phép nhân làkích thước(uint32_t)là dư thừa. Để biết cách chính xác để tiến con trỏ, hãy xemfloat* end_azi = Begin_azi + GetTotalPointCount();

2) nênTrỏ tới uint32_tcon trỏ kiểu tính toán độ lệch địa chỉ trước khi chuyển đổi thànhcon trỏ nổikiểu.

bắt đầu_aziCách đúng phải như thế này:

Begin_azi = const_cast(reinterpret_cast(_begin + GetChannelCount() + Index::SIZE));

Tại sao nó hoạt động một phần trước đây? từ cppreference

Số học con trỏ

Nếu con trỏ P trỏ vào một phần tử của mảng có chỉ số I thì

  • P+N và N+P là các con trỏ trỏ đến một phần tử của cùng một mảng có chỉ số I+N
  • PN là con trỏ trỏ đến một phần tử của cùng mảng có chỉ số {tt|IN}}

Hành vi này chỉ được xác định nếu cả con trỏ ban đầu và con trỏ kết quả đều trỏ vào các phần tử của cùng một mảng hoặc một quá khứ kết thúc của mảng đó.

Không ai biết tiền boa ở đâubắt đầu_aziChỉ ra những lỗi tính toán. Vì vậy không có gì đảm bảo rằng chương trình sẽ thực thi đúng hay sai.

Về c++ - truy cập dữ liệu từ bộ đệm được tạo bởi boost, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/57495300/

29 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress