free 导致 malloc 产生不同的结果
free causing different results from malloc
下面是我编写的用于打印字符串中不同字符组合的 C 程序。
这不是一种有效的方法,因为该算法会创建大量额外的字符串。但是我的问题不是关于如何更有效地解决这个问题。
该程序工作(虽然效率低下)并打印字符串字符的不同组合(正确)。但是,当我尝试 free
正在创建的额外字符串时,我 运行 出现了问题。导致问题的 free
位于 recur_printc
函数的末尾(已注释)。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 3
void recur_printc(char *, int, char *);
int main()
{
char str[] = "abc";
char *print_arr = malloc(N * sizeof(char));
//Call recur_print
recur_printc(print_arr, 0, str);
free(print_arr);
return 0;
}
void recur_printc( char *print_arr, int index, char *remaining)
{
int i, j, rem_len, index_4_next;
//base case, only last character remaining
if(strlen(remaining) == 1)
{
print_arr[index] = remaining[0];
//Print the print_arr
for(i=0; i<N; i++)
{
printf("%c",print_arr[i]);
}
printf("\n");
return;
}
//If more than one character remaining
else
{
rem_len = strlen(remaining);
for(i=0; i<rem_len; i++)
{
//Add one character to print_arr
print_arr[index] = remaining[i];
//now create the string with remaining characters
char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
index_4_next = 0;
for(j=0; j<rem_len; j++)
{
if(j != i)
{
remaining_for_next[index_4_next] = remaining[j];
index_4_next++;
}
}
//call recur_print
recur_printc(print_arr, index+1, remaining_for_next);
//Free the remainin_for_next
/*------This is causing issues----*/
//free(remaining_for_next);
remaining_for_next = NULL;
}
}
}
当我在 gdb
中 运行 这个程序时,我注意到当 i=1
对于 recur_print
的第一个实例时,一个 st运行ge 事情发生了与 malloc
。
执行此行时:
char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
虽然rem_len-1
等于2
,但是malloc分配了3
个字节,然后整个算法就失败了,因为这个字符串的代码strlen
中的某处被使用了(这将是 3 而不是 2)。不确定发生了什么。(当我注释掉 free()
行时不会发生这种情况。)
下面是 gdb 输出:
42 char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
(gdb) print remaining_for_next
= 0x0
(gdb) n
43 index_4_next = 0;
(gdb) print remaining_for_next
= 0x602030 "@ `"
(gdb) print rem_len-1
= 2
(gdb) q
抱歉这么久 post。再一次,我的问题不是关于如何以不同(和更好)的方式打印组合。我的问题是为什么当我尝试释放 remaining_for_next
字符串时上面的代码失败(也许是 malloc 受到影响的原因)。
我还没有仔细梳理过所有内容,但我相信 remaining_for_next
字符串不会有空字符终止。您使用的 strlen()
不包含字符串长度中的空字符,然后将字符串复制为字符数组。它可能是开始搜索的地方。我想第一次从自身调用 recur_printc
时,行为不会是你想要的。尝试手动将空字符附加到 remaining_for_next
,看看是否能解决问题。
每次创建字符串时,您都没有附加空终止符,这会导致错误。
所以改变这个:
for(j=0; j<rem_len; j++) {
if(j != i) {
remaining_for_next[index_4_next] = remaining[j];
index_4_next++;
}
}
对此:
for(j=0; j<rem_len; j++) {
if(j != i) {
remaining_for_next[index_4_next] = remaining[j];
index_4_next++;
}
}
remaining_for_next[index_4_next] = '[=11=]';
输出:
gsamaras@gsamaras:~/Desktop/px$ gcc -Wall main.c
gsamaras@gsamaras:~/Desktop/px$ ./a.out
abc
acb
bac
bca
cab
cba
提示:几乎总是必须以空终止字符串,不要忘记它!
重要编辑:
正如 alk 所注意到的,您需要对此进行更改:
char *remaining_for_next = malloc((rem_len - 1) * sizeof(char));
对此:
char *remaining_for_next = malloc((rem_len) * sizeof(char));
为了使space成为空终止符。
好问题,+1。
下面是我编写的用于打印字符串中不同字符组合的 C 程序。
这不是一种有效的方法,因为该算法会创建大量额外的字符串。但是我的问题不是关于如何更有效地解决这个问题。
该程序工作(虽然效率低下)并打印字符串字符的不同组合(正确)。但是,当我尝试 free
正在创建的额外字符串时,我 运行 出现了问题。导致问题的 free
位于 recur_printc
函数的末尾(已注释)。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 3
void recur_printc(char *, int, char *);
int main()
{
char str[] = "abc";
char *print_arr = malloc(N * sizeof(char));
//Call recur_print
recur_printc(print_arr, 0, str);
free(print_arr);
return 0;
}
void recur_printc( char *print_arr, int index, char *remaining)
{
int i, j, rem_len, index_4_next;
//base case, only last character remaining
if(strlen(remaining) == 1)
{
print_arr[index] = remaining[0];
//Print the print_arr
for(i=0; i<N; i++)
{
printf("%c",print_arr[i]);
}
printf("\n");
return;
}
//If more than one character remaining
else
{
rem_len = strlen(remaining);
for(i=0; i<rem_len; i++)
{
//Add one character to print_arr
print_arr[index] = remaining[i];
//now create the string with remaining characters
char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
index_4_next = 0;
for(j=0; j<rem_len; j++)
{
if(j != i)
{
remaining_for_next[index_4_next] = remaining[j];
index_4_next++;
}
}
//call recur_print
recur_printc(print_arr, index+1, remaining_for_next);
//Free the remainin_for_next
/*------This is causing issues----*/
//free(remaining_for_next);
remaining_for_next = NULL;
}
}
}
当我在 gdb
中 运行 这个程序时,我注意到当 i=1
对于 recur_print
的第一个实例时,一个 st运行ge 事情发生了与 malloc
。
执行此行时:
char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
虽然rem_len-1
等于2
,但是malloc分配了3
个字节,然后整个算法就失败了,因为这个字符串的代码strlen
中的某处被使用了(这将是 3 而不是 2)。不确定发生了什么。(当我注释掉 free()
行时不会发生这种情况。)
下面是 gdb 输出:
42 char *remaining_for_next = malloc((rem_len-1) * sizeof(char));
(gdb) print remaining_for_next
= 0x0
(gdb) n
43 index_4_next = 0;
(gdb) print remaining_for_next
= 0x602030 "@ `"
(gdb) print rem_len-1
= 2
(gdb) q
抱歉这么久 post。再一次,我的问题不是关于如何以不同(和更好)的方式打印组合。我的问题是为什么当我尝试释放 remaining_for_next
字符串时上面的代码失败(也许是 malloc 受到影响的原因)。
我还没有仔细梳理过所有内容,但我相信 remaining_for_next
字符串不会有空字符终止。您使用的 strlen()
不包含字符串长度中的空字符,然后将字符串复制为字符数组。它可能是开始搜索的地方。我想第一次从自身调用 recur_printc
时,行为不会是你想要的。尝试手动将空字符附加到 remaining_for_next
,看看是否能解决问题。
每次创建字符串时,您都没有附加空终止符,这会导致错误。
所以改变这个:
for(j=0; j<rem_len; j++) {
if(j != i) {
remaining_for_next[index_4_next] = remaining[j];
index_4_next++;
}
}
对此:
for(j=0; j<rem_len; j++) {
if(j != i) {
remaining_for_next[index_4_next] = remaining[j];
index_4_next++;
}
}
remaining_for_next[index_4_next] = '[=11=]';
输出:
gsamaras@gsamaras:~/Desktop/px$ gcc -Wall main.c
gsamaras@gsamaras:~/Desktop/px$ ./a.out
abc
acb
bac
bca
cab
cba
提示:几乎总是必须以空终止字符串,不要忘记它!
重要编辑:
正如 alk 所注意到的,您需要对此进行更改:
char *remaining_for_next = malloc((rem_len - 1) * sizeof(char));
对此:
char *remaining_for_next = malloc((rem_len) * sizeof(char));
为了使space成为空终止符。
好问题,+1。