C++运行报错写入数组时缓冲区溢出 如何输出指定首字母开头的随机单词
问题原因与修复方案
报错根源
- 手动管理的动态数组未做扩容:你初始化
int* amounts_of_words = new int[s];、int* array_of_K = new int[sz];时,s和sz的初始值都是1,意味着这两个数组仅能存储1个int元素。后续遍历字符串的过程中,你直接向数组中写入多个元素,完全没有扩容操作,越界写入堆内存直接触发缓冲区溢出。 - 下标与随机数逻辑存在越界风险:你硬编码了
rand() % 4作为随机下标,如果实际统计到的k开头单词数量不足4,访问array_of_K[randomN]也会触发越界。
修复方案
优先使用C++标准库容器替代手动管理的动态数组,std::vector会自动处理内存扩容和释放,不需要手动管理大小,从根源避免缓冲区溢出。同时可以简化逻辑,直接遍历所有单词并筛选首字母为k的单词存入容器,不需要单独存序号二次查找。
修复后可运行代码
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <vector> #include <string> #include <ctime> #include <cstring> using namespace std; int main() { srand(time(NULL)); char str1[150] = "knight kevin once said that maybe that kind of process is necessary to him pushing him on and on and it is very painful he knows."; cout << "原字符串:" << str1 << endl; vector<string> k_words; // 用strtok拆分所有单词 char* token = strtok(str1, " .?!"); while (token != NULL) { // 判断首字母是否为k/K if (token[0] == 'k' || token[0] == 'K') { k_words.push_back(token); } token = strtok(NULL, " .?!"); } if (k_words.empty()) { cout << "没有找到首字母为k的单词" << endl; return 0; } // 随机取一个k开头的单词 int random_idx = rand() % k_words.size(); cout << "随机选取的k开头单词:" << k_words[random_idx] << endl; return 0; }
内容的提问来源于stack exchange,提问作者Gleb Shapovalov
相关产品推荐
相关产品推荐

