在c#中通过指针更改char结构字段

pdsfdshx  于 2023-10-15  发布在  C#
关注(0)|答案(2)|浏览(117)

我几乎绝望,因为我与c指针斗争:-(。
我有一个带char字段的结构体,用于在ESP8266的闪存中存储配置值。这在以前的固件版本像一个魅力。然而,我决定进行一次主要的SDK /固件升级,并构建新的一切。但是一旦我想改变设置,系统就崩溃了.下面是我的设置-struct和相关函数

typedef struct{
    char device_id[11];
    char sta_ssid[32];
...
} SYSCFG;

void CFG_Save(SYSCFG *sysCfg);
void CFG_Load(SYSCFG *sysCfg);
void CFG_Init(SYSCFG *sysCfg);

设置的初始化为:

void CFG_Init(SYSCFG *sysCfg)
{
    memset(sysCfg, 0, sizeof(SYSCFG));
    uint8_t mac[6];
    char devId[11]; 
    esp_efuse_mac_get_default(mac);
    sprintf(devId, "ESP_%02X%02X%02X", mac[3], mac[4], mac[5]);
    strncpy((char *)sysCfg->device_id, (char *)&devId, 10);
    sysCfg->customConfig = 0;
    CFG_Save(sysCfg);
}

我看到调试输出时,它工作正常,没有发生崩溃。此外,加载工作,但只要我做以下,它崩溃。

printf("saving key: %s, input: %s, size: %d\r\n", key, input, sizeof(config->sta_ssid) - 1);
strncpy(config->sta_ssid, input, sizeof(config->sta_ssid) - 1);

但是,它会输出调试消息:

saving key: ssid, input: Netgear, size: 31

我在main函数中分配内存:

SYSCFG *sysCfg;
sysCfg = malloc(sizeof(SYSCFG));

我做错了什么。

jm81lzqq

jm81lzqq1#

  • sysCfg = malloc(sizeof(SYSCFG));这是未初始化的内存。
  • sprintf(devId, "ESP_%02X%02X%02X"这将创建一个10个字符+ null终止的字符串
  • strncpy((char *)sysCfg->device_id, (char *)&devId, 10);这将复制10个字符,并且没有null终止,因为strncpy从来就不打算用于以null终止的字符串作为开始。这是一个危险的功能,应该完全避免。
  • (从char*转换到char*是没有意义的,但这不是bug的来源。

解决方案:strcpy(sysCfg->device_id, devId);
详情请查看Is strcpy dangerous and what should be used instead?

pgx2nnw8

pgx2nnw82#

我做了一些修改,想缩小问题的范围。在我的主文件中,我现在有:

SYSCFG sysCfg;
SYSCFG * const cfgPtr = &sysCfg;
ESP_LOGI(TAG, "Custom Config: %d, Address: %p", sysCfg.customConfig, cfgPtr);

这给了我:

I (538) ota: Custom Config: 0, Address: 0x3ffea704

那我就叫

openssl_server(cfgPtr, &ssids);

void openssl_server(SYSCFG *config, char (*ssids)[1024])
{
    sprintf("pointer address: %p\n", config);
    ...

当它应该打印指针地址时就会崩溃。

Core  0 panic'ed (LoadStoreError). Exception was unhandled.

地址的传递似乎有些不对劲。

相关问题