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

CP210x串口通信程序数组大小<25触发Segmentation fault问题求助

问题:CP210x USB转UART通信程序数组大小小于25时触发段错误

我正在开发一个与CP210x USB转UART桥通信的小型程序。程序逻辑简单,但每当将发送消息数组的大小wm_size设置为小于25时,就会触发Segmentation fault。按我的逻辑,wm_size设为2就足够,但实际并非如此。通过试验发现将wm_size设为25可解决问题,请问这是什么原因?

出现问题的代码如下:

HANDLE prog_com_port;

prog_com_port = CreateFileA("\\\\.\\COM4",
                        GENERIC_READ | GENERIC_WRITE,   //Request Read and Write Acess
                        0,                              //Block others from sharing Acess
                        NULL,                           //Disable Security features
                        OPEN_EXISTING,                  //Only open existing device
                        FILE_ATTRIBUTE_NORMAL,          //Used to set atributes and flags
                        NULL); 
                                                    //Handle to 
if(prog_com_port == INVALID_HANDLE_VALUE)
{
    printf("Opening COM port failed - INVALID_HANDLE_VALUE\n");
    CloseHandle(prog_com_port);
    return 1;
}
else
    printf("COM port was opened successfully \n");

SetupCommState(prog_com_port);
Sleep(2);
#define wm_size 25
int messageLength = 2;
char W_message[wm_size] = {0x01,0x01}; 

long unsigned int * bytes_sent;
BOOL Status;

Status = WriteFile(prog_com_port,                       // Handle to the Serial port
                &W_message,                             // Pointer to message buffer
                messageLength,                          // No of bytes to write
                bytes_sent,                             // Pointer to number of bytes written
                NULL);
if(!Status)
{
    printf("Failed to write to COM port - 0x00 \n");
    CloseHandle(prog_com_port);
    return 2;
}

CloseHandle(prog_com_port);

原因分析与修复方案

段错误和wm_size的大小无关,本质是未初始化指针引发的非法内存访问:

  1. 代码里long unsigned int * bytes_sent;只声明了指针,未分配有效内存空间,属于野指针。WriteFile需要一个有效的DWORD*(即unsigned long*)指针来存储实际写入的字节数,传入野指针后,函数会尝试往随机内存地址写入数据,直接触发段错误。
  2. 当wm_size设为25时,栈内存布局刚好发生变化,野指针碰巧指向了进程有权访问的栈空间,所以没报错——这只是偶然的巧合,属于未定义行为,不是真正解决了问题。

修复代码

把bytes_sent改成实际变量,传入它的地址给WriteFile:

// 替换原指针声明为实际变量
unsigned long bytes_sent;

// 调用WriteFile时传入变量地址,同时修正缓冲区指针(W_message本身就是数组首地址)
Status = WriteFile(prog_com_port,
                W_message,
                messageLength,
                &bytes_sent,
                NULL);

另外注意:&W_message是指向整个数组的指针,虽然能正常工作,但直接用W_message更规范,它会自动退化为数组首元素的指针,完全符合WriteFile对缓冲区参数的要求。

内容的提问来源于stack exchange,提问作者Casper Knudsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:40:26