尝试将char指针追加到固定字符串时出现内存异常

时间:2016-01-18 11:19:59

标签: c exception memory strcpy char-pointer

我有一个要求,我必须获得一个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);

1 个答案:

答案 0 :(得分:2)

  1. 你看,在 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,则可能会出现溢出。

  2. 您正在将char **指针传递给strlen()

    char *rssiResult = malloc(strlen(&rssi) + strlen(&rssiVal) + 1);
    /*                               ^ wrong --------^ remove them */
    

    strlen()期望指向char *终止的字节序列的nul指针。这样做会调用未定义的行为。

  3. 你在这里再做一次

    strcpy(rssiResult, &rssi);
    /*                 ^ same problem, remove it */
    

    不同之处在于rssi + 1&rssi + 1不同,因此当指针在这些函数中的任何一个中被解引用时,会发生未定义的行为

  4. 我很惊讶看到这样的代码,因为编译器应警告不兼容的指针类型,有两个可能的原因看到这个代码而且它们是,或者你不编译带有警告标志的代码 gcc -Wall或您完全忽略警告。

  5. 此外,在使用指针之前,请务必检查malloc()是否成功。

  6. 注意:不要使用strlen(),就像长度存储在某处一样,每次调用strlen()需要计算长度时,请将长度存储在某处。这为您提供了另一个优势,而不是使用strcpy(),它将再次搜索nul终止符字节,因为您可以使用memcpy()存储长度。您可能没有注意到任何性能改进,但至少您会知道您利用了如何工作来实现更好的性能。