C语言指针引用错误值:无法发送变量中存储的目标值
你的代码里有几个关键的指针操作错误,导致始终发送初始的"Incorrect test",我来帮你拆解并修正:
核心问题:指针操作完全误解
你试图用指针mydatapnt切换要发送的数据,但对指针的赋值、解引用逻辑完全搞错了,甚至用到了未初始化的指针——这会导致程序出现未定义行为(比如崩溃、数据乱码),自然无法发送目标值。
错误1:未初始化的指针mydatapnt
static uint8_t *mydatapnt;声明了一个指针,但没有给它分配有效内存,也没让它指向任何已存在的变量。直接解引用这个指针(比如*mydatapnt = ...)是非法操作,会破坏随机内存区域。
错误2:setup()里的无效赋值
*mydata = mydatapnt;
*mydata是mydata数组的第一个字节(char类型),而mydatapnt是一个指针(存储内存地址,通常是4/8字节)。把指针的值赋值给单个字节,完全是类型不匹配,只会把mydata的第一个字符改成乱码,根本达不到切换数据的目的。
错误3:loop()里的错误操作
*mydatapnt = strdata; Serial.println(*mydatapnt + "");
- 同样,
*mydatapnt是单个字节,strdata是指针,赋值类型不匹配;而且mydatapnt未初始化,解引用它是致命错误。 *mydatapnt + ""也不对:单个字符加字符串字面量会做指针算术(把字符的ASCII值作为偏移量加到字符串地址上),不是你想要的字符串拼接,打印出来的要么是乱码要么是空内容。
错误4:send()函数硬编码使用mydata
你想发送strdata的内容,但send()里一直固定使用mydata数组,而且你从来没有正确把strdata的内容复制到mydata,也没让发送函数指向strdata。
修正方案
根据你的需求,有两种常见的修正方式,选一种适合你的场景:
方案1:把目标字符串复制到mydata数组(适合需要修改原有数组内容的场景)
因为mydata是固定大小的字符数组,我们可以用字符串复制函数把strdata的内容拷贝进去:
// 注意:你原来的"Successfull"拼写多了一个l,建议改成"Successful" static uint8_t mydata [] = "Incorrect test"; uint8_t *strdata = (uint8_t*)"Successful test"; void send(){ if (LMIC.opmode & OP_TXRXPEND) { Serial.println(F("OP_TXRXPEND, not sending")); } else { // 用strlen获取实际字符串长度,比sizeof(mydata)-1更准确 LMIC_setTxData2(1, mydata, strlen((char*)mydata), 0); Serial.println(F("Packet queued")); } } void setup(){ // 把strdata的内容复制到mydata,确保不超出数组大小 strncpy((char*)mydata, (char*)strdata, sizeof(mydata)-1); mydata[sizeof(mydata)-1] = '\0'; // 手动添加字符串结束符,避免溢出 } void loop(){ // 正确打印字符串 Serial.println((char*)mydata); // 如果需要动态切换内容,可以在这里重新执行strncpy }
方案2:用指针动态切换发送目标(适合不需要修改数组,直接切换数据源的场景)
定义一个指针指向当前要发送的数据,需要切换时改变指针指向即可:
static uint8_t *currentTxData; // 指向当前要发送的数据 uint8_t *strdata = (uint8_t*)"Successful test"; static uint8_t mydata [] = "Incorrect test"; void send(){ if (LMIC.opmode & OP_TXRXPEND) { Serial.println(F("OP_TXRXPEND, not sending")); } else { LMIC_setTxData2(1, currentTxData, strlen((char*)currentTxData), 0); Serial.println(F("Packet queued")); } } void setup(){ currentTxData = strdata; // 初始指向目标字符串 } void loop(){ Serial.println((char*)currentTxData); // 如果需要切换回原数据,只需修改指针: // currentTxData = mydata; }
关键知识点回顾
- 指针
ptr存储的是内存地址,*ptr是取这个地址对应的内容。 - 要让指针指向另一个变量/字符串,直接赋值
ptr = target(比如currentTxData = strdata),不要解引用后赋值。 - 字符串字面量(比如
"test")是只读的,如果你需要修改内容,要把它复制到可写的字符数组里。
内容的提问来源于stack exchange,提问作者Maartenw
相关产品推荐
相关产品推荐

