C++指向结构体指针数组的指针添加元素时段错误排查求助
先帮你梳理几个大概率导致段错误的问题,都是从你贴的代码里能直接定位到的:
1. bin_search里的优先级错误导致逻辑混乱
你在bin_search开头写了这么一行:
if((int*)start[COUNT_POS] == 0)
这里的运算符优先级出问题了!start[COUNT_POS]会先执行,也就是取start数组里索引为COUNT_POS的元素(这是个void*指针),然后把它转成int*,再判断这个指针是不是空。但你实际想判断的是当前数组的元素计数是否为0,正确的写法应该是:
if(((int*)start)[COUNT_POS] == 0)
因为start指向的是数组的起始位置(前面两个int存count和size),所以要先把start转成int*,再取COUNT_POS索引的值。这个错误会导致当数组为空时,你的判断逻辑不生效,直接进入后面的二分查找循环,访问非法内存触发段错误。
2. find_place里的索引混淆,访问了错误的内存
在find_place的循环里,你先遍历Start数组里的每个net,然后对当前net的sublevel(商店数组)做二分查找:
bin_search(((net*)(Start)[i])->sublevel, key, pos, find, compare_shop);
当找到目标商店时,你却用了((net*)(Start)[pos])->sublevel来调用add_goods——这里完全错了!pos是当前net的商店数组里的索引,不是Start数组里net的索引。正确的写法应该是先拿到当前i对应的net,再取它的商店数组里pos位置的商店,然后用这个商店的sublevel:
// 正确的写法 net* current_net = (net*)Start[i]; shop* target_shop = (shop*)current_net->sublevel[pos]; add_goods(target_shop->sublevel, Pnew);
你原来的写法会去访问Start数组里pos索引的元素(可能根本不存在,或者不是你要找的net),直接越界访问内存,必然触发段错误。
3. 商店的sublevel可能未初始化
你给Start(第一层的net数组)做了init_list初始化,但有没有给每个商店的sublevel(第三层的商品数组)也调用init_list?如果某个商店的sublevel是NULL,那么在add_goods里操作((shop*)(Start))->sublevel时,就是在操作空指针,执行bin_search或者addtosort的时候直接触发段错误。
4. add_goods的参数引用问题
add_goods的第一个参数是void **&Start,也就是void**的引用,但你调用的时候传的是((net*)(Start)[pos])->sublevel——这是一个void**类型的指针值,不是引用。如果你的编译器允许这种隐式转换,可能会导致后续的数组扩容操作(ExpandArrPtr)无法正确修改原指针,进而导致内存访问错误。建议把add_goods的参数改成void **start,或者确保传入的是一个可修改的引用类型变量。
先把这些问题逐一排查修复,应该就能解决段错误了。
内容的提问来源于stack exchange,提问作者Alex Fr

