我有一个要求,我必须获得一个int的RFID RSSI值并将其转换为char指针并附加到它。以下是我的表现。
char *epcBytes = (char *)tag_operation_report->tag.epc.bytes;
int rssiString = fabs(tag_operation_report->tag.rssi);
char *rssiVal = (char *)rssiString;
char* rssi = "rssi";
char *rssiResult = malloc(strlen(&rssi) + strlen(&rssiVal) + 1);
strcpy(rssiResult, &rssi);
strcpy(rssiResult + strlen(&rssi), &rssiVal);
char *result = malloc(strlen(&epcBytes) + strlen(&rssiResult) + 1);
strcpy(result, &epcBytes);
strcpy(result + strlen(&epcBytes), &rssiResult);
data = (void*)result;
但是我在运行代码时遇到以下异常。
Unhandled exception at 0x00007FFBD017B2E5 (msvcr120d.dll) in RFIDTest.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
我在这里做错了什么?当我在在线C编译器上运行它时,它运行正常。此行引发此异常,
strcpy(rssiResult, &rssi);
答案 0 :(得分:2)
你看,在c char *
中不是字符串类型,它只是一个指针。所以这个
char *rssiVal = (char *)rssiString;
完全错误,您正在向指针强制转换整数。这是由标准定义的,但它绝不会做你正在尝试的,将整数转换为你需要snprintf()
之类的字符串,这是一个例子
char string[100];
int result;
result = snprintf(string, sizeof(string),
"%.0f", fabs(tag_operation_report->tag.rssi));
if ((result < 0) || (result >= sizeof(string))
error_please_dont_use_string();
另外,fabs()
会返回double
而不是int
,因此如果您将值分配给int
,则可能会出现溢出。
您正在将char **
指针传递给strlen()
char *rssiResult = malloc(strlen(&rssi) + strlen(&rssiVal) + 1);
/* ^ wrong --------^ remove them */
而strlen()
期望指向char *
终止的字节序列的nul
指针。这样做会调用未定义的行为。
你在这里再做一次
strcpy(rssiResult, &rssi);
/* ^ same problem, remove it */
不同之处在于rssi + 1
与&rssi + 1
不同,因此当指针在这些函数中的任何一个中被解引用时,会发生未定义的行为。
我很惊讶看到这样的代码,因为编译器应警告不兼容的指针类型,有两个可能的原因看到这个代码而且它们是,或者你不编译带有警告标志的代码 gcc -Wall
或您完全忽略警告。
此外,在使用指针之前,请务必检查malloc()
是否成功。
注意:不要使用strlen()
,就像长度存储在某处一样,每次调用strlen()
需要计算长度时,请将长度存储在某处。这为您提供了另一个优势,而不是使用strcpy()
,它将再次搜索nul
终止符字节,因为您可以使用memcpy()
存储长度。您可能没有注意到任何性能改进,但至少您会知道您利用了如何工作来实现更好的性能。