C语言libusb开发调用libusb_get_device_descriptor触发段错误求解
问题产生原因
核心是C语言函数参数默认是值传递,你在first_get_device_descriptor内对形参dev的赋值,完全不会修改main函数中定义的实参dev:
main中定义的libusb_device *dev没有初始化,是野指针。- 调用
first_get_device_descriptor(devices, dev)时,传给函数的是dev指针的值拷贝,也就是函数内部的形参dev是独立的局部变量,和外层main里的dev不是同一个内存地址。 - 函数内执行
dev = devices[10],只是修改了局部形参的指向,让局部dev指向了合法的设备地址,所以函数内调用libusb_get_device_descriptor能正常运行,但这个修改完全不会同步到外层的dev。 - 等调用
second_get_device_descriptor(dev)时,传入的还是main里那个从未被赋值的野指针,libusb_get_device_descriptor访问非法内存地址,直接触发段错误。
修复方案
两种常用改法二选一即可,额外建议加设备列表长度校验,避免硬编码索引越界:
- 方案1:让函数直接返回获取到的设备指针,不需要传参输出
- 方案2:如果要通过参数输出指针,需要传入
dev的二级指针(即dev变量的地址),才能修改外层变量的值
修复后参考代码
#include <stdio.h> #include <stdlib.h> #include <libusb-1.0/libusb.h> // 方案1:直接返回设备指针 libusb_device* first_get_device_descriptor(libusb_device ** devices){ struct libusb_device_descriptor device_descriptor; libusb_device *target_dev = devices[10]; int ret = libusb_get_device_descriptor(target_dev, &device_descriptor); // 可自行补充ret的错误判断逻辑 return target_dev; } void second_get_device_descriptor(libusb_device *dev){ struct libusb_device_descriptor device_descriptor; int ret = libusb_get_device_descriptor(dev, &device_descriptor); // 可自行补充ret的错误判断逻辑 } int main(int argc, char* argv[]) { libusb_device **devices; libusb_device *dev = NULL; // 指针定义时记得初始化 libusb_context *context = NULL; ssize_t device_cnt; libusb_init(&context); device_cnt = libusb_get_device_list(context, &devices); // 加索引越界校验,避免设备数不足11个时访问越界 if (device_cnt < 11) { printf("设备数量不足,找不到索引为10的设备\n"); goto cleanup; } dev = first_get_device_descriptor(devices); //Android device found second_get_device_descriptor(dev); cleanup: libusb_free_device_list(devices, 1); libusb_exit(context); return 0; }
如果要用二级指针传参的方案,把first函数改成下面的写法即可:
// 方案2:二级指针传参输出 void first_get_device_descriptor(libusb_device ** devices, libusb_device ** dev){ struct libusb_device_descriptor device_descriptor; *dev = devices[10]; int ret = libusb_get_device_descriptor(*dev, &device_descriptor); } // main中对应调用方式改为:first_get_device_descriptor(devices, &dev);
内容的提问来源于stack exchange,提问作者Lacoudasse
相关产品推荐
相关产品推荐

