从C中的函数返回后,数组元素发生变化

时间:2019-02-10 06:56:08

标签: c string pointers arm

我有一个运行在ARM体系结构上的简单C程序。我们有两个全局数组:

char RxB[400];
char GPS[150];

我有一个类似的函数,该函数搜索并找到keytermChar之间的子字符串。结果子字符串定义为函数的参数:

SEARCH_STATUS findString_chr(char *src, char *key, int key_size, char termChar, char *dst, int desLen)
{
    char *temp, *tempchar;
    temp = strstr(src, key);
    if (temp == NULL)
        return STR_KEY_NOT_FOUND;
    else
        temp += key_size;

    tempchar = strchr(temp, termChar);
    if (!tempchar)
        return STR_TERMINATOR_NOT_FOUND;

    uint8_t siz = (uint8_t)(tempchar - temp);
    if (siz > desLen)
        return STR_OVERFLOW;
    memcpy(dst, temp, siz);
    dst[siz] = '\0';
    return STR_FOUND;
}

在我的 main.c 中,我有一个简单的代码,如下所示:

do {
    ST = findString_chr(RxB, key, strlen(key), '$', GPS, 150);
    // Some delay here
    // Some other codes
} while (some conditions);

请注意,RxB值每1秒变化一次,因为它是通过串行通讯获得的。

我的问题是,据我所知,退出findStringchr函数后,GPS的值不应更改,因为没有人操纵它的元素。但是,当我调试代码时,发现GPS数组的值仍在变化。

有人有什么主意吗?

P.S: main.c (更多信息):

    cnt = 0;        
    HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);

    do {
        ST = findString_chr(RxB, key, strlen(key), '$', GPS, 150);
        findString_chrchr(GPS, 2, st, 2);
        if ((st[0] == 'A') && (ST == STR_FOUND)) {
            findString_chrchr(GPS, 3, lati, 10);
            findString_chrchr(GPS, 5, longi, 11);  
            sendState = GPS_ACTIVE;
            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
            HAL_Delay(1000);    
            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
            HAL_Delay(1000);    
            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
            HAL_Delay(1000);    
            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
            HAL_Delay(1000);                    
            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin,GPIO_PIN_RESET); 
        }
        HAL_Delay(1000);
        HAL_IWDG_Refresh(&hiwdg);           
        gpsCounter++;
        if (gpsCounter > (TIMEOUT_GPS/1000)) {      
            sendState = GPS_TIMEOUT;
            memcpy(lati, "1111.1111", 10);
            memcpy(longi, "01111.1111", 11);    
            gpsCounter = 0;
        }
    } while ((sendState == GPS_VOID) && (cnt != 1));

findStringchrchr()函数在两个后续逗号之间返回一个子字符串:

SEARCH_STATUS findString_chrchr(char *src, int commaNumber, char *dst, int desLen) {
    char *temp = src, *end;
    int cnt = 0;
    while (1) {
        temp = strchr(temp, ',') + 1;
        if (!temp)
            return STR_KEY_NOT_FOUND;
        else {
            cnt++;
            if (cnt == commaNumber) {
                end = strchr(temp, ',');
                int D = (end - temp);
                if (D >= desLen)
                    return STR_OVERFLOW;
                if (D == 0)
                    dst[0] = '\0';
                } else {
                    memcpy(dst, temp, D);
                    dst[D] = '\0';
                }   
                break;
            }
        }
    }
    return STR_FOUND;
}

2 个答案:

答案 0 :(得分:4)

您在函数中与GPS参数相对应的位置传递dst

在该函数中,您具有:

memcpy(dst,temp,siz);

这肯定会在执行数组GPS时修改数组Traceback (most recent call last): File "/home/pi/Downloads/gspread2.py", line 6, in <module> from oauth2client.service_account import ServiceAccountCredentials File "/usr/local/lib/python2.7/distpackages/oauth2client/service_account.py", line 25, in <module> from oauth2client import client File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 39, in <module> from oauth2client import transport File "/usr/local/lib/python2.7/dist-packages/oauth2client/transport.py", line 17, in <module> import httplib2 File "/usr/local/lib/python2.7/dist-packages/httplib2/__init__.py", line 28, in <module> import email.FeedParser ImportError: No module named 'email.FeedParser' ,因此您断言“不应更改GPS的值,因为没有人可以操纵其元素” 是完全错误的

答案 1 :(得分:1)

您的问题未提供足够的信息来进行完整的诊断,您不清楚您的意思是 GPS的值不应更改,因为没有人操纵其元素。这里有一些想法:

  • 根据乔纳森(Jonathan)的诊断,如果找到密钥,GPS将由您的函数findString_chr进行修改。你没想到吗?

  • 您是否观察到在调用GPS 之后更改了全局数组findString_chr()的内容?您没有发布相关代码,完全有可能是副作用引起的。

函数findString_chr本身有问题:

  • uint8_t中的类型uint8_t siz = (uint8_t)(tempchar - temp);是嵌入式软件开发实践的典型代表,受某些编码标准的鼓励,其副作用非常严重:temp与{{1之间的距离}}大于tempchar,仅取值的毫无意义的部分是没有意义的,256应该具有类型sizint并使用类型{{1 }}不会节省任何运行时空间,只是一个错误。

  • 测试size_t关闭了1。目标数组中需要的空间为int8_t字节,用于说明空终止符,您可以将其设置为偏移量if (siz > desLen)

这是更正的版本:

siz+1

关于您的问题,将完整的源代码发布到出现问题的最小程序中可能不可行,但是函数siz中存在的错误类型可能存在于其他地方,并导致内存损坏。例如,给定问题中提到的全局声明的情况下,写入SEARCH_STATUS findString_chr(const char *src, const char *key, int key_size, char termChar, char *dst, int desLen) { const char *temp, *tempchar; int siz; temp = strstr(src, key); if (temp == NULL) return STR_KEY_NOT_FOUND; temp += key_size; tempchar = strchr(temp, termChar); if (!tempchar) return STR_TERMINATOR_NOT_FOUND; siz = tempchar - temp; if (siz >= desLen) return STR_OVERFLOW; memcpy(dst, temp, siz); dst[siz] = '\0'; return STR_FOUND; } 的串行通信例程有可能超出该数组的末尾,而该例程可能位于RAM中的findString_chr数组之前。

编辑:按照发布的其他信息,还有其他问题:

  • 即使RxB不返回GPS,您也可以无条件呼叫findString_chrchr(GPS, 2, st, 2);。这是一个问题,因为如果字符串中的逗号数量太小,findString_chr的行为不确定。

实际上,函数STR_FOUND有问题:

  • findString_chrchr行之后还有一个额外的findString_chrchr,导致}块与外部if (D == 0) dst[0] = '\0';绑定。

  • 找不到
  • else中的if中的temp = strchr(temp, ',') + 1;。您应该在递增之前测试NULL

  • 在计算要复制的长度时,您不会测试是否还有另一个','。如果temp,,则int D = (end - temp);可能为负,从而导致未定义的行为。

以下是经过纠正和简化的版本:

temp