2016-02-29 20 views
8

Mam dwa dodatkowe znaki dodawane do początku mojego napisu i nie mogę wydawać się dowiedzieć dlaczego. Postacie nie pojawiają się nawet w kodzie. Brak mi tutaj. To jest mój kod:Dodatkowe znaki dodane do początku ciągu?

#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; 
} 

Z jakiegoś powodu, kod produkuje to:

Enter characters: gggg 

Input: PEgggg 

Kiedy należy produkujących to:

Enter characters: gggg 

Input: gggg 
+3

Na co wskazuje 'input'? – immibis

+0

Nota boczna: ponieważ 'chars' jest zmienną globalną, nie ma sensu w' zwracających znakach; '. –

+0

@barakmanos byłoby lepiej usunąć zmienną globalną i mieć ją lokalną do 'wektora' –

Odpowiedz

5

Przeszedłeś niezainicjowanej input do vector() i używane to, więc wywołałeś niezdefiniowane zachowanie.

Spróbuj zmienić char *input na char *input = "".

Usunąć również free(chars);, lub napotkasz problem podwójnie wolny.

+0

Występuje również przeciek pamięci z pamięcią 'calloc'd w wektorze. –

+1

Inną kwestią jest to, że pamięć przydzielona przez 'calloc' nigdy nie jest zwalniana. Najlepszym sposobem, aby to zrobić, będzie 'vector', który wywoła' free (newlist) '; więc wartość początkowa 'input' musi być albo' calloc (1,1); ', albo' NULL' z 'vector()' mającym specjalny przypadek do obsługi wejścia zerowego. –

1

Brakuje inicjalizacji znaku *, co prowadzi do niezdefiniowanego zachowania. Pls zainicjować znak *

5

Myślę, że masz jedno lub więcej niezainicjowanych pól. Mam te ostrzeżenia przy próbie kompilacji:

$ 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. 

Gdy używam Asan what is ASan?, pojawia się następujący błąd:

$ 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

Wszystkie punkty @MikeCat są wymienione są poprawne, tylko dodać, że pamięć przydzielona przez calloc nie zostanie uwolniony, co prowadzi do wycieku pamięci. Można free go jak powiedział @MM w komentarzu, ale na następny raz, aby uniknąć wycieków pamięci, można użyć 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

Trzeba usunąć wolnego (druk) i przypisać do pointers.First zwany podwójny darmowy, a ostatnio spowodował wyrzucenie rdzenia. Pracuję na Ubuntu, a moja wersja gcc to 4.8.4

Powiązane problemy