You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:18:34