C++向数组添加元素仅成功添加1个后停止的问题求助
问题分析与代码修正
你的代码只能生成一个元素的核心问题有两个,结合你熟悉的Java/Kotlin概念解释:
原代码的关键问题
- 循环范围少处理一个元素:外层循环
outOn < CURSORS_AMOUNT-1相当于Java里调用split后只取前CURSORS_AMOUNT-1个元素,直接丢掉最后一段内容。 - 未处理无分隔符的最后一段:只有找到逗号时才会将子串存入结果数组,要是最后一段后面没有逗号(就像Java
split里的最后一个元素),这段内容会被直接丢弃,也不会添加字符串终止符'\0'。 - 内存浪费:每次创建的
temp数组大小是整个buffer的长度,相当于Java里明明只需要存一个短字符串,却创建了和原字符串一样长的数组。
修正后的代码
TCHAR** schemeValueToArray(TCHAR* buffer, DWORD size) { const TCHAR delim = ','; TCHAR** out = new TCHAR*[CURSORS_AMOUNT]; int lastPos = 0; // 对应Java中截取子串的起始索引 int outIndex = 0; // 遍历buffer直到末尾,或结果数组填满 while (lastPos < size && outIndex < CURSORS_AMOUNT) { // 找到当前段的结束位置:要么是分隔符,要么是buffer末尾 int currentEnd = lastPos; while (currentEnd < size && buffer[currentEnd] != delim) { currentEnd++; } // 计算当前段长度,分配刚好足够的内存(+1用于存终止符'\0') int segmentLength = currentEnd - lastPos; TCHAR* temp = new TCHAR[segmentLength + 1]; // 复制当前段的字符,对应Java里的substring(lastPos, currentEnd) for (int i = 0; i < segmentLength; i++) { temp[i] = buffer[lastPos + i]; } temp[segmentLength] = '\0'; // C++必须手动加终止符,Java自动维护字符串结束 out[outIndex] = temp; outIndex++; // 跳过分隔符(如果还没到buffer末尾) if (currentEnd < size) { lastPos = currentEnd + 1; } else { break; } } // 将结果数组中未使用的位置设为nullptr,避免野指针 while (outIndex < CURSORS_AMOUNT) { out[outIndex] = nullptr; outIndex++; } return out; }
关键逻辑说明(对应Java/Kotlin概念)
- 这段代码的逻辑和Java的
String.split(",")完全一致:lastPos记录每次截取子串的起始位置,就像Java里indexOf找到分隔符后,下一次从index+1开始。- 内层循环找到当前子串的结束位置(分隔符或字符串末尾),对应Java
String.indexOf(',', lastPos)的作用。 - 只分配刚好能存下当前子串的内存(+1存
'\0'),避免不必要的内存浪费。 - 手动添加
'\0'是C的强制要求——Java/Kotlin的字符串会自动维护长度信息,但C的C风格字符串必须用'\0'标记结尾,否则读取时会出现乱码或越界。
额外提醒
C++没有自动垃圾回收机制,用完返回的数组后,必须手动释放内存,否则会造成内存泄漏:
// 释放示例 TCHAR** result = schemeValueToArray(buffer, size); // 使用result... for (int i = 0; i < CURSORS_AMOUNT; i++) { delete[] result[i]; // 先释放每个子串的内存 } delete[] result; // 再释放数组本身
内容的提问来源于stack exchange,提问作者Joshua Miller
相关产品推荐
相关产品推荐

