8

I have two extra characters being added to the beginning of my string and I can't seem to find out why. The characters don't even appear in the code. I'm at a loss here. This is my code:

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

For some reason, the code produces this:

Enter characters: gggg

Input: PEgggg

When it should be producing this:

Enter characters: gggg

Input: gggg
Nickname97
  • 101
  • 5

5 Answers5

6

All the points @MikeCat are said are correct, just to add that the memory allocated by calloc is not freed which leads to a memory leak. You can free it as said by @M.M in a comment, but for next time, to avoid memory leaks, you can use 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.

Community
  • 1
  • 1
Box Box Box Box
  • 5,094
  • 10
  • 49
  • 67
5

You passed uninitialized input to vector() and used it, so you invoked undefined behavior.

Try changing char *input to char *input = "".

Also remove free(chars);, or you will encounter double-free problem.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • There is also a memory leak with the `calloc`d memory in vector. – Michael Albers Feb 29 '16 at 04:16
  • 1
    Another issue is that the memory allocated by `calloc` is never freed. The best way to do this will be for `vector` to call `free(newlist)` ; so the initial value of `input` needs to either be `calloc(1,1);` , or `NULL` with `vector()` having a special case to handle null input. – M.M Feb 29 '16 at 04:17
5

I think you have one or more uninitialized fields. I get these warnings when I try to compile:

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

When I use ASanwhat is ASan? , I get the following error:

$ 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
Brian Cain
  • 14,403
  • 3
  • 50
  • 88
1

Initialization of the char * is missing and hence leading to undefined behavior. Pls initialize the char *

frp farhan
  • 445
  • 5
  • 19
0

You need delete free(print) and assign to pointers.First called double free,and last caused core dumped.I work on ubuntu and my gcc version is 4.8.4

wjsszka
  • 9
  • 1