我在这里有点困惑。主要内容:
int main() {
char **symbols = (char **) malloc(3 * sizeof(char *)); // allocate 3 (char *)'s
for (int i = 0; i < 3; i++)
symbols[i] = (char *)malloc(3); // allocate string of length 3
}
然后用户在一行中输入三个字符串符号,以空格分隔:
111 010 101
然后我将这个缓冲的字符串解析为一个字符串数组:
void parseSymbols(char *line, int k, char **symbols) {
// k == 3
// Ignore leading spaces
while (*line != '\0' && is_whitespace(*line))
line++;
char *p = strtok(line, " ");
int cnt = 0;
symbols[cnt++] = p;
while (p) {
p = strtok(NULL, " \n");
symbols[cnt++] = p;
}
// Let's call this FOOBAR
//for (int i = 0; i < k; i++)
// printf("%d. %s\n", i, symbols[i]);
回到 main,当我打印 symbols 中的 3 个字符串时,我得到了这个:
0. '111'
1. '010'
2. ' s'
但是当我取消注释掉最后两行 parseSymbols 时,我得到:
0. '111'
1. '010'
2. '101'
为什么 FOOBAR block “修复”了我的字符串数组,更重要的是,我怎样才能让 parseSymbols 正常工作而不必在屏幕上打印一些东西? symbols[2] 是否需要以'\0'结尾? (但是 strtok 不是为我做的吗?)
最佳答案
您的第一个问题是您通过将 strtok
的结果指针分配给符号表而导致内存泄漏。这是因为您只是复制对标记下一个开头的引用,而不是复制这些行中的结果字符串:symbols[cnt++] = p;
接下来,您应该通过将结果分配给您的符号表来确保您没有超过 k。您的代码总是在符号表的最后位置写入 NULL。一旦解析 3 个符号,您将写入未分配的内存,导致未定义的行为。
我建议先纠正这些问题,然后再试一次。
请注意,strtok 通过将标记末尾的分隔符替换为“\0”来修改您的原始缓冲区,因此无需复制字符串。另请注意,strtok 会跳过其中一个定界符的连续出现。因此,您的第一个循环可以替换为检查第一个标记的长度是否 >0(或者换句话说,结果字符串的第一个字节是 != '\0'
请注意,C 字符串总是需要比您要存储的空间多 1 个字节的空间。这个额外的字节用于 '\0' 终止。在您的示例中,您正在解析 3 个字节的 block ,同时每个 block 仅分配 3 个字节(应该是 4 个):symbols[i] = (char *)malloc(3);//分配长度为 3 的字符串
关于c - 字符串数组中的最后一个字符串(从 strtok 解析)有垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14545407/