C++中存储char*的list调用sort()无法按字母序排序的解决方法
问题产生原因
你的代码存在三个核心问题,共同导致排序失效、甚至数据存储异常:
- 内存复用错误:你只在循环外分配了一次长度为20的char数组,循环内每次读取单词都是往同一块内存地址写入内容,再把同一个地址push到list中。最终list里所有元素都指向同一个内存地址,存储的全是最后一次读取到的单词,根本不存在三个独立的待排序元素。
- 排序比较逻辑错误:就算修复内存问题,为每个单词单独分配内存存储,
list<char*>存储的是指针类型(本质是内存地址数值),默认sort规则是直接比较指针的地址大小,而非指针指向的C字符串内容的字典序,自然无法得到预期的字母排序结果。 - 语法与逻辑写法问题:你写的
list<DT> list1= new <DT>list();本身不符合C++语法,list作为STL容器可以直接在栈上定义实例,不需要手动new分配。另外用!cin.eof()作为循环判断条件是常见写法错误,会在文件读取到末尾时多插入一次无效垃圾数据。
正确实现方案
优先推荐使用STL原生字符串类型规避指针问题,实现最简单也最不容易出错:
#include <iostream> #include <list> #include <string> int main() { std::list<std::string> wordList; std::string tempWord; // 直接以cin读取结果作为循环条件,避免eof判断的逻辑缺陷 while (std::cin >> tempWord) { wordList.push_back(tempWord); } // string默认重载了<运算符,按字典序比较,直接调用sort即可 wordList.sort(); // 此处可添加遍历逻辑验证排序结果 return 0; }
如果因为特殊场景必须使用char*存储C风格字符串,需要手动给sort传入基于strcmp实现的自定义比较器,同时注意每次读取单词时单独分配内存,使用完后手动释放避免内存泄漏:
#include <iostream> #include <list> #include <cstring> // 自定义C字符串比较逻辑:返回true表示a应该排在b前面 bool cstrCompare(const char* a, const char* b) { return std::strcmp(a, b) < 0; } int main() { std::list<char*> wordList; char readBuf[20]; while (std::cin >> readBuf) { // 为每个单词单独分配内存,不要复用同一块缓冲区 char* tempWord = new char[std::strlen(readBuf) + 1]; std::strcpy(tempWord, readBuf); wordList.push_back(tempWord); } // 传入自定义比较器完成字典序排序 wordList.sort(cstrCompare); // 使用完list后必须手动释放每个char*指向的内存,避免内存泄漏 for (char* ptr : wordList) { delete[] ptr; } return 0; }
上述实现会逐位比较字符的ASCII值,对你测试的三个单词,第四个字符I(ASCII 73)小于L(ASCII 76),第五个字符E(ASCII 69)小于S(ASCII 83),最终会得到预期的APPIE、APPLE、APPLS排序结果。
内容的提问来源于stack exchange,提问作者Jasmin Wilson
相关产品推荐
相关产品推荐

