2016-02-29 129 views
8

我有兩個額外的字符被添加到我的字符串的開頭,我似乎無法找出原因。這些字符甚至不出現在代碼中。我在這裏不知所措。這是我的代碼:額外的字符添加到字符串的開頭?

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

char *chars; 

char* vector(char input, char *newlist); 

int main(){ 

    char *input, *out = "Input: "; 

    printf("Enter characters: ");     
    while(1){ 
     char i = getchar();       //get input 
     if(i == '\n'){ 
      break;         //detect a return key 
     } else{ 
      input = vector(i, input);    //call vector 
     } 
    } 

    char * print = (char *)malloc(1 + strlen(input) + strlen(out)); 
    strcpy(print, out);        //concat the strings 
    strcat(print, input); 

    printf("\n%s", print);       //print array 

    free(print); 
    free(input); 
    free(chars); 

    return 0;          //exit 
} 

char* vector(char in, char *newlist){ 

    int length = strlen(newlist);     //determine length of newlist(input) 

    chars = (char*)calloc(length+2, sizeof(char)); //allocate more memory 
    strcpy(chars, newlist);       //copy the array to chars 
    chars[length] = in;        //appened new character 
    chars[length + 1] = '\0';      //append end character 

    return chars; 
} 

出於某種原因,該代碼會產生這樣的:

Enter characters: gggg 

Input: PEgggg 

當它應該是產生這樣的:

Enter characters: gggg 

Input: gggg 
+3

'input'指向什麼? – immibis

+0

注意:由於'chars'是一個全局變量,'return chars;'沒有意義。 –

+0

@barakmanos最好刪除全局變量,並將它放在本地的'vector'上。 –

回答

5

您通過初始化inputvector()和使用它,所以你調用未定義的行爲

嘗試將char *input更改爲char *input = ""

也刪除free(chars);,否則您將遇到雙免費問題。

+0

這裏還有一個向量中帶有'calloc'd內存的內存泄漏。 –

+1

另一個問題是'calloc'分配的內存永遠不會被釋放。最好的方法是'vector'調用'free(newlist)';所以'input'的初始值需要是'calloc(1,1);'或'NULL','vector()'有一個特殊情況來處理null輸入。 –

1

char *的初始化丟失,從而導致未定義的行爲。請初始化char *

5

我認爲您有一個或多個未初始化的字段。我得到這些警告,當我嘗試編譯:

$ clang -Weverything vector.c 
vector.c:15:18: warning: implicit conversion loses integer precision: 'int' to 'char' [-Wconversion] 
     char i = getchar();       //get input 
      ~ ^~~~~~~~~ 
vector.c:19:31: warning: variable 'input' may be uninitialized when used here [-Wconditional-uninitialized] 
      input = vector(i, input);    //call vector 
           ^~~~~ 
vector.c:11:16: note: initialize the variable 'input' to silence this warning 
    char *input, *out = "Input: "; 
      ^
       = NULL 
vector.c:40:33: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion] 
    chars = (char*)calloc(length+2, sizeof(char)); //allocate more memory 
        ~~~~~~ ~~~~~~^~ 
vector.c:38:18: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32] 
    int length = strlen(newlist);     //determine length of newlist(input) 
     ~~~~~~ ^~~~~~~~~~~~~~~ 
vector.c:5:7: warning: no previous extern declaration for non-static variable 'chars' [-Wmissing-variable-declarations] 
char *chars; 
    ^
5 warnings generated. 

當我使用阿三what is ASan,我得到以下錯誤:

$ echo 1 2 3 | ./a.out 
Enter characters: 
================================================================= 
==23718==ERROR: AddressSanitizer: attempting double-free on 0x60200000ef70 in thread T0: 
    #0 0x4a5f4b in free /home/development/llvm/3.7.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:30:3 
    #1 0x4cd631 in main (/home/brian/src/so/a.out+0x4cd631) 
    #2 0x7f3b94ef5a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f) 
    #3 0x4174c8 in _start (/home/brian/src/so/a.out+0x4174c8) 

0x60200000ef70 is located 0 bytes inside of 7-byte region [0x60200000ef70,0x60200000ef77) 
freed by thread T0 here: 
    #0 0x4a5f4b in free /home/development/llvm/3.7.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:30:3 
    #1 0x4cd5fa in main (/home/brian/src/so/a.out+0x4cd5fa) 
    #2 0x7f3b94ef5a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f) 

previously allocated by thread T0 here: 
    #0 0x4a63b4 in calloc /home/development/llvm/3.7.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:56:3 
    #1 0x4cd67c in vector (/home/brian/src/so/a.out+0x4cd67c) 
    #2 0x4cd57b in main (/home/brian/src/so/a.out+0x4cd57b) 
    #3 0x7f3b94ef5a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f) 

SUMMARY: AddressSanitizer: double-free /home/development/llvm/3.7.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:30:3 in free 
==23718==ABORTING 
6

@MikeCat都表示,所有的點是正確的,只是補充說,通過calloc分配的內存不釋放導致內存泄漏。您可以free它通過在評論@MM說,但接下來的時間,以避免內存泄漏,您可以使用valgrind

Let's take your program, as hash.c . Got to the command line and compile it, for eg :

gcc hash.c -Wall 

If your program compiles successfully, an executable or out file will appear. As we have not specified the name of the executable, it's default name will be a.out . So let's run it with valgrind :

valgrind -- leak-check=full ./a.out 

This will run executable, along with valgrind, and if there is a memory leak, it will show it when the executable ends.


If you do not have valgrind installed, you can install it from here .

0

您需要刪除免費(打印),並分配給pointers.First稱爲雙免費,最後導致核心轉儲。我在Ubuntu上工作,我的gcc版本是4.8.4