C 中带有 malloc 的子字符串函数返回不正确的值
Substring function in C with malloc returning incorrect value
我正在用 C 为一阶逻辑公式实现解析器。要检查二进制连接公式(即形式为 (A BinaryConnective B)),我需要拆分字符串并检查 A 和 B 是否为公式。我使用 subString 函数完成了此操作,并从 partone 和 parttwo(分别为 A 和 B)调用它:
char *partone(char *g) {
//Given the formula (A*B) this returns A
return subString(g, 1, binPosition(g));
}
char *parttwo(char *g) {
//Given the formula (A*B) this returns B
return subString(g, binPosition(g) + 1, strlen(g) - 1);
}
子字符串函数如下:
char *subString(char *g, int start, int end) {
//the substring includes index start but does not include the end index.
char *substr = malloc(sizeof(char)*(end - start));
int i;
for(i = 0; i < (end - start); i++) {
substr[i] = g[start + i];
}
return substr;
}
当我传递除取反公式以外的任何函数时这会起作用(我们使用字符“-”表示取反)。例如,当我传递 (-X[xz]>X[yz]) 时,程序 returns "Not a Formula",但如果我不带否定地编写相同的程序,它就可以完美运行。问题是为 partone() 返回的 substr 是“-X[xz]$”,其中 $ 可以是我认为之前存储在内存中的任何随机字符。任何想法为什么只在这种情况下发生?我是C的新手,到处都看过。
提前致谢。
您忘记了 subString
函数中的终止 NUL。你的 malloc 应该看起来像
char* substring = (char*)malloc (sizeof (char)*(end-start+1));
最后你需要用 0 终止结果:
substring [end-start]=0;
并且由于 c 中的数组是零索引的,我很惊讶你没有丢失 A 部分的前导“-”,因为 partone
使用 [=15 调用 subString
=] 作为 start
.
编辑:C/C++ 中有很多用于字符串操作的内置函数。您应该使用它们,因为它们已经过测试和优化。我已经很多年没有使用 C 了,所以我不是最新的 C++11 中合适的方法是什么,但 Google 可能会告诉你。
编辑:正如 chux 所指出的,您的 end
参数的含义并不完全清楚。所以你需要检查parttwo
中的strlen (g)-1
或subString
中的循环条件,并在我的malloc语句中增加到+2
。
OP 对 start
和 end
的使用没有正式化,但我假设它们是所需子字符串的第一个和最后一个字符的字符串的索引。
回想一下,在 C 中,数组索引以 0
开头,因为 g[0]
是存储在 g
的字符串的第一个字符。
如果是这种情况,代码需要分配 end - start + 1 + 1
space 并确保分配的字符数组末尾有空字符 '[=17=]'
。
char *subString(const char *g, int start, int end) {
if (end < start || start < 0) {
return NULL;
}
size_t size = 2u + end - start;
char *substr = malloc(size);
if (substr) {
int i;
for(i = 0; i < (end - start); i++) {
substr[i] = g[start + i];
}
substr[i] = '[=10=]';
}
return substr;
}
其他simplifications/improvements可能
我正在用 C 为一阶逻辑公式实现解析器。要检查二进制连接公式(即形式为 (A BinaryConnective B)),我需要拆分字符串并检查 A 和 B 是否为公式。我使用 subString 函数完成了此操作,并从 partone 和 parttwo(分别为 A 和 B)调用它:
char *partone(char *g) {
//Given the formula (A*B) this returns A
return subString(g, 1, binPosition(g));
}
char *parttwo(char *g) {
//Given the formula (A*B) this returns B
return subString(g, binPosition(g) + 1, strlen(g) - 1);
}
子字符串函数如下:
char *subString(char *g, int start, int end) {
//the substring includes index start but does not include the end index.
char *substr = malloc(sizeof(char)*(end - start));
int i;
for(i = 0; i < (end - start); i++) {
substr[i] = g[start + i];
}
return substr;
}
当我传递除取反公式以外的任何函数时这会起作用(我们使用字符“-”表示取反)。例如,当我传递 (-X[xz]>X[yz]) 时,程序 returns "Not a Formula",但如果我不带否定地编写相同的程序,它就可以完美运行。问题是为 partone() 返回的 substr 是“-X[xz]$”,其中 $ 可以是我认为之前存储在内存中的任何随机字符。任何想法为什么只在这种情况下发生?我是C的新手,到处都看过。
提前致谢。
您忘记了 subString
函数中的终止 NUL。你的 malloc 应该看起来像
char* substring = (char*)malloc (sizeof (char)*(end-start+1));
最后你需要用 0 终止结果:
substring [end-start]=0;
并且由于 c 中的数组是零索引的,我很惊讶你没有丢失 A 部分的前导“-”,因为 partone
使用 [=15 调用 subString
=] 作为 start
.
编辑:C/C++ 中有很多用于字符串操作的内置函数。您应该使用它们,因为它们已经过测试和优化。我已经很多年没有使用 C 了,所以我不是最新的 C++11 中合适的方法是什么,但 Google 可能会告诉你。
编辑:正如 chux 所指出的,您的 end
参数的含义并不完全清楚。所以你需要检查parttwo
中的strlen (g)-1
或subString
中的循环条件,并在我的malloc语句中增加到+2
。
OP 对 start
和 end
的使用没有正式化,但我假设它们是所需子字符串的第一个和最后一个字符的字符串的索引。
回想一下,在 C 中,数组索引以 0
开头,因为 g[0]
是存储在 g
的字符串的第一个字符。
如果是这种情况,代码需要分配 end - start + 1 + 1
space 并确保分配的字符数组末尾有空字符 '[=17=]'
。
char *subString(const char *g, int start, int end) {
if (end < start || start < 0) {
return NULL;
}
size_t size = 2u + end - start;
char *substr = malloc(size);
if (substr) {
int i;
for(i = 0; i < (end - start); i++) {
substr[i] = g[start + i];
}
substr[i] = '[=10=]';
}
return substr;
}
其他simplifications/improvements可能