我有一个运行在ARM体系结构上的简单C程序。我们有两个全局数组:
char RxB[400];
char GPS[150];
我有一个类似的函数,该函数搜索并找到key
和termChar
之间的子字符串。结果子字符串定义为函数的参数:
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;
}
答案 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
应该具有类型siz
或int
并使用类型{{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