我正在编写一个函数来使用正则表达式在字符串中查找变量。该功能工作正常,但是当我尝试释放保存我正在评估的字符串的临时char *时,glibc调用无效指针错误并且程序中止。在下面的代码中,如果从未输入while循环,则不会发生崩溃。
我做错了什么?
int parse_variables(size_t read_len)
{
regex_t comp_regex;
int start = 0;
char *command_copy = malloc(sizeof(command));
strcpy(command_copy, command);
if (regcomp(&comp_regex, "[$][^0-9_][A-Z0-9_]+", REG_EXTENDED) != 0)
{
pmesg(1, "Regex compilation failed. Not parsing for variables.\n");
return -1;
}
regmatch_t pmatch;
int var_match = regexec(&comp_regex, command_copy+start, comp_regex.re_nsub+1, &pmatch, 0);
pmesg(1, "The initial value of var_match is %i.\n", var_match);
while (var_match == 0) // We are finding instances matching the regex
{
int length = pmatch.rm_eo-pmatch.rm_so;
char* var_name = malloc(length*sizeof(char));
strncpy(var_name, command_copy + start + pmatch.rm_so, length);
pmesg(1, "The length is: %i - %i = %i.\n", pmatch.rm_eo, pmatch.rm_so, length);
pmesg(1, "The variable's name is: %s.\n", var_name);
free(var_name);
start += pmatch.rm_eo;
var_match = regexec(&comp_regex, command_copy+start, comp_regex.re_nsub+1, &pmatch, 0);
}
free(command_copy-start);
return 0;
}
答案 0 :(得分:4)
您永远不会修改command_copy
,但您正试图在command_copy-start
处释放一个位置。
将free(command_copy-start);
行更改为free(command_copy);
。
从未输入循环时它起作用的原因,因为start
永远不会从零变化。
答案 1 :(得分:1)
我在您的代码中看到了一些问题:
什么是command
?使用sizeof(command)
不会给字符串长度command
;您需要malloc
从strlen(command) + 1
到strcpy
的{{1}}到command
的缓冲区。
Zooba关于command_copy
的答复中的陈述。
答案 2 :(得分:1)
将来,您会考虑使用代码格式吗?只是编码风格的一个例子:
int parse_variables(size_t read_len)
{
regex_t comp_regex;
regmatch_t pmatch;
int start = 0;
char* command_copy;
int var_match;
Some_result_t regcomp_result;
command_copy = malloc(sizeof(command));
strcpy(command_copy, command);
regcomp_result = regcomp (&comp_regex, /* <description of what this parameter does> */
"[$][^0-9_][A-Z0-9_]+", /* <description of what this parameter does> */
REG_EXTENDED); /* <description of what this parameter does> */
if (regcomp_result != 0 )
{
pmesg(1, "Regex compilation failed. Not parsing for variables.\n");
return -1;
}
var_match = regexec (&comp_regex, /* <description of what this parameter does> */
command_copy + start, /* <description of what this parameter does> */
comp_regex.re_nsub + 1, /* <description of what this parameter does> */
&pmatch, /* <description of what this parameter does> */
0); /* <description of what this parameter does> */
pmesg (1,
"The initial value of var_match is %i.\n",
var_match);
while (var_match == 0) // We are finding instances matching the regex
{
int length;
char* var_name;
length = pmatch.rm_eo-pmatch.rm_so;
var_name = malloc(length * sizeof(char));
strncpy (var_name,
command_copy + start + pmatch.rm_so,
length);
pmesg (1,
"The length is: %i - %i = %i.\n",
pmatch.rm_eo,
pmatch.rm_so,
length);
pmesg (1,
"The variable's name is: %s.\n",
var_name);
free(var_name);
start += pmatch.rm_eo;
var_match = regexec (&comp_regex,
command_copy+start,
comp_regex.re_nsub+1,
&pmatch,
0);
} /* while (var_match == 0) */
free(command_copy-start);
return 0;
}
除代码样式外,代码功能与原始代码相同,但从C ++转换为C.变量声明是用C ++编写的。
答案 3 :(得分:0)
我还没有完成心理体操,但是使用调试器来运行这段代码应该是微不足道的。从malloc()返回什么地址,以及传递给free()的是什么?
另外,我认为将计算指针传递给free()是不好的形式。您应该传递从malloc()返回的相同值。如果需要,创建另一个变量。
答案 4 :(得分:0)
请注意,strncpy()
不会表现出您认为相同的效果。如果源的字符串长度与目标中可用的字符数相同,则生成的字符串不以null结尾。这几乎不是你想要的。
您可以通过执行以下操作来解决此问题:
char* var_name = malloc((length + 1)*sizeof(char));
strncpy(var_name, command_copy + start + pmatch.rm_so, length);
var_name[length] = 0;