我会回到我的函数char **my_str_to_word_array(char *str)
,目的是在每个不可打印的ASCII字符处分离字符串,并将其包含在二维数组的新行中。
不可打印的ASCII字符应用作分隔符,且不应包含在行中。
示例:
char *test = "My name is John Doe.\nI have 0 GPA.\nI will survive." ;
char **array = my_str_to_word_array(test) ;
array[0] = "My name is John Doe." (zero terminated string)
array[1] = "I have 0 GPA." (zero terminated string)
array[2] = "I will survive." (zero terminated string)
array[3] = NULL
我有两个问题:
1.如果在我的测试main()
中,my_str_to_word_array调用下面有一个printf()
,那么传递给printf()
的格式将包含在数组中,所以我得出结论,内存读取错误。
1.当我尝试free()
阵列时,我得到一个错误:
double free or corruption (out)
[1] 33429 IOT instruction (core dumped) ./libmy
size_t get_words_number(char const *str)
{
size_t count = 0;
const char *i = str;
while (*i != 0) {
if (isprint(*i)) {
count++;
}
while (*i != 0 && isprint(*i)) {
i++;
}
i++;
}
return count;
}
char **free_corrupted_array(char **array, size_t i)
{
size_t j = 0;
while (j < i) {
free(array[j]);
j++;
}
free(array);
return NULL;
}
char **fill_array(char **array, const char *str, size_t word_count)
{
size_t word_size = 0, j = 0;
const char *i = str;
while (j < word_count) {
while (*i != 0 && isprint(*i)) {
word_size++;
i++;
}
array[j] = strndup(i - word_size, word_size);
if (!array[j]) {
return free_corrupted_array(array, j);
}
word_size = 0;
j++;
while (!isprint(*i)) {
i++;
}
}
array[j] = NULL;
return array;
}
char **my_str_to_word_array(char const *str)
{
char **word_array = NULL;
size_t word_count = 0;
if (!str) {
return NULL;
}
word_count = get_words_number(str);
word_array = malloc(word_count * sizeof(char *));
if (!word_array) {
return NULL;
}
word_array = fill_array(word_array, str, word_count);
return word_array;
}
void my_free_word_array(char **word_array)
{
if (!word_array) {
return;
}
while (*word_array != NULL) {
free(*word_array);
word_array++;
}
free(word_array);
}
int main(int argc, char **argv)
{
const char *test = "My name is John Doe.\nI have 0 GPA.\nI will survive.";
char **word_array = my_str_to_word_array(test);
while (*word_array != NULL) {
printf("%s\n", *word_array);
word_array++;
}
printf("Test print original size %lu\n", strlen(test));
my_free_word_array(word_array);
return 0;
}
并且输出:
My name is John Doe.
I have 0 GPA.
I will survive.
Test print original size %lu
Test print original size 50
double free or corruption (out)
[1] 33429 IOT instruction (core dumped) ./libmy
你看到问题了吗?
2条答案
按热度按时间ufj5ltwl1#
错误:
get_words_number
超出了界限(相差1),可能会在字符串之后读取任意内存(请检查main
中包含的示例)。1.您需要在阵列中增加一个插槽,以便放置终止
NULL
。1.如果以后需要输入指针,请停止抖动(在
my_free_word_array
和main
的打印循环中)。建议:
1.下一次通过包含所有需要的头来创建Minimal, Reproducible Example;
strndup
不是标准的(除非您有__STDC_ALLOC_LIB__
并将__STDC_WANT_LIB_EXT2__
定义为1)。1.您根本不需要
free_corrupted_array
函数。7uhlpewt2#
OP的代码错过了对 * 空字符 * 的检查。@Costantino Grana
候选
get_words_number()
校正和简化:计数从“非单词”到“单词”的转换。
将
unsigned char*
用于所有字符和is...()
函数的定义用途。