我正在开发具有功能的c ++应用程序
//ControllerCore.cpp
Report ControllerCore::GetReport() {
unsigned char buf[256];
int res = 0;
while (res == 0) {
res = get_unsigned_char*(buf, sizeof(buf));
if (res < 0)
printf("Unable to read()\n");
#ifdef WIN32
Sleep(50);
#else
usleep(50 * 1000);
#endif
}
Report report = Report();
report.data = buf;
report.dataLength = res;
return report;
}
报告定义为
//Report.h
struct Report
{
public:
unsigned char* data;
int dataLength;
};
当ContollerCore :: GetReport()返回时,它将report.data分配给指向我可以很好使用的无符号字符数组的指针。但是,当调用者尝试打印report.data时,数组的值将更改。
//Main.cpp
int RequestReport() {
Report report = core.GetReport();
for (int i = 0; i < report.dataLength; i++) {
std::cout << "0x" << std::hex << (int)report.data[i] << ", ";
}
std::cout << std::endl;
return 1;
}
答案 0 :(得分:1)
您正在返回一个指向本地数组的指针。 ControlerCore::GetReport
返回后,buf
超出范围并被销毁。此后任何尝试访问它的行为都会导致不确定的行为。
您需要使Report
实际上直接保存数据。最简单的方法是使用std::vector
:
struct Report
{
std::vector<unsigned char> data;
// don't need dataLength anymore since std::vector knows its size
};
Report ControllerCore::GetReport() {
Report report;
report.data.resize(256);
int res = 0;
while (res == 0) {
res = get_data(report.data.data(), report.data.size());
}
report.data.resize(res);
return report;
}
现在Report
只有一个成员,可能不再需要它了,您可以直接返回std::vector<unsigned char>
。
如果要避免std::vector
使用的动态分配,可以改用std::array
(或原始数组):
struct Report
{
std::array<unsigned char, 256> data;
size_t dataLength; // back now, since the length of the data won't match the size of the contianer
};
Report ControllerCore::GetReport() {
Report report;
int res = 0;
while (res == 0) {
res = get_data(report.data.data(), report.data.size());
}
report.dataLength = res;
return report;
}
这避免了动态分配,但是由于std::array
不能像std::vector
那样有效地移动,因此会产生额外的数据副本。这意味着除非在您的平台上动态分配特别慢,否则std::vector
版本可能会更快。
答案 1 :(得分:0)
您可以尝试使用report.data本身而不是buf。
val myDataReads = new Reads[MyData] {
//the JsValue passed to this reads should conform to structure expected by MyData
def reads(jsv:JsValue) = JsResult = {
//I want to pick each field, check its value and print error is something is wrong
val uuidOptionReads:Reads[Option[UUID]] = (JsPath \ "field1").readNullable[UUID]; //not sure if this is correct
//now I have got new Reads but how do I get uuid from here?
uuidOptionReads.reads(/*reads expects a JsValue but I don't know what to pass here.*/)
/*I want to repeat the above logic for other fields*/
}
}