2015-06-14 63 views
4

下面是我寫的一個C程序,用於打印字符串中不同字符的組合。free from malloc

這不是一種有效的方法,因爲這種算法創造了很多額外的字符串。然而,我的問題不是關於如何更有效地解決這個問題。

該程序工作(效率低下),並打印字符串(正確)的不同組合。但是,當我嘗試free額外的字符串正在創建我遇到問題。導致問題的free在thr 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 cahracter 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=1recur_print第一個實例,一個奇怪的事情發生與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 
$3 = 0x0 
(gdb) n 
43    index_4_next = 0; 
(gdb) print remaining_for_next 
$4 = 0x602030 "@ `" 
(gdb) print rem_len-1 
$5 = 2 
(gdb) q 

很抱歉的長期職位。再次,我的問題不是關於如何以不同(更好)的方式打印聯合。我的問題是,當我嘗試釋放remaining_for_next字符串(可能爲什麼malloc受到影響)時,上述代碼失敗的原因。

+0

「*免費導致問題... *」如果處理動態分配的內存導致問題,您可能想轉向使用內存檢查工具,如Valgind(https://valgrind.org)。 – alk

回答

1

每次創建字符串時,都不會追加導致錯誤的空終止符。

所以改變這樣的:

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] = '\0'; 

輸出:

[email protected]:~/Desktop/px$ gcc -Wall main.c 
[email protected]:~/Desktop/px$ ./a.out 
abc 
acb 
bac 
bca 
cab 
cba 

提示:它幾乎總是一個必須爲null終止您的字符串, 別忘記了!


重要編輯:

由於ALK注意到了,你需要這個改變:爲了騰出空間爲

char *remaining_for_next = malloc((rem_len) * sizeof(char)); 

char *remaining_for_next = malloc((rem_len - 1) * sizeof(char)); 

本空終止符。


不錯的問題+1。

+0

它是'0'或'NUL'或零或終止符。但是'NULL'是不同的。 – alk

+0

@alk正確。編輯,現在好嗎? – gsamaras

+1

我想說代碼仍然錯過了爲'0'結束符分配空間。 – alk

2

我還沒有通過一個精細的齒梳,但我相信remaining_for_next字符串將不會有空字符終止。您正在使用strlen(),它不包含字符串長度中的空字符,然後將該字符串複製爲一個字符數組。它可能是一個開始搜索的地方。我會想象第一次從自己調用recur_printc時,行爲將不會是你想要的。嘗試手動將空字符追加到remaining_for_next並查看是否可以解決問題。