0

So, my task is to make and return a copy of a given string, and in case it has failed (for example, hit enter) to return NULL. However, when I hit Enter, the program continues to work and to print out some garbage values. The fun fact though, is that the program works just fine when I run it through the Debugger (which chalenges me the most). I don't find a simple explanation for what might've gone wrong. Or is it the problem with my compiler?

#include <stdio.h>
#include <stdlib.h>
// listing functions
char *ft_strdup(char *src);
int main(void)
{
    // input of a string
    char c[200];
    scanf("%[^\n]%*c", c);

    // calling a function
    char *f = ft_strdup(c);
    printf("\n%s\n", f);
    free(f);
    return 0;
}

char *ft_strdup(char *src)
{
    int i = 0;
    // itearting to get the 'length' of string src
    while (src[i] != '\0')
        ++i;
    // if user has inputted nothing - return NULL and break the function
    if (i == 0)
    {
        return NULL;
    }
    // otherwise, make a copy of the string
    char *x = malloc(i+1);
    int j = 0;
    while (j != i)
    {
        x[j] = src[j];
        ++j;
    }
    x[i+1] = '\0';
    // print out and return
    printf("%s\n%s\n%i", x, src, i);
    return x;
}
PRO grmr
  • 1
  • 1
  • Because `c++` has a concept of Undefined Behavior where anything can happen when you violate rules. – drescherjm Feb 12 '20 at 12:55
  • 1
    when you return `NULL` and assigning it to the ` char *f` and try to `printf()` you have UB. You need to validate your pointer: `if(f) printf("\n%s\n", f); else printf("enter");` – Raffallo Feb 12 '20 at 12:56
  • Dereferencing NULL is undefined behavior. Anything can and should happen. – theWiseBro Feb 12 '20 at 12:57
  • you might be interested in how C++ iostreams handle this. `std::cin >> x` will set `x` to `0` if the extraction failed and you can check the state of `std::cin` to confirm it succeeded. I would advise not to use a null pointer to indicate failure, it will lead to more problems similar to the current one – 463035818_is_not_an_ai Feb 12 '20 at 13:00
  • 2
    BTW, What is worse is when undefined behavior produces a result that you expect giving you a false sense that the program is correct and is working. This can happen. – drescherjm Feb 12 '20 at 13:00
  • Why is this question tagged `c++`? It does not use C++ idioms, nor does it use C++ header files. – Eljay Feb 12 '20 at 13:25

2 Answers2

0

It prints garbage value because char c[200]; is not initialized that mean It has garbage value inside.

char c[200] = {0}; 

try this and probably get some crash due to NULL pointer access.

add this to avoid crash

if (f != NULL) {
   printf("\n%s\n", f);
   free(f);
}
idris
  • 488
  • 3
  • 6
0

The program has undefined behavior by two reasons.

The first one is that the array cwas not initialized

char c[200];

So it has indeterminate values and if the user just press the Enter key the array will not be changed.

You could initialize it in C++ like

char c[200] = {};

or in C like

char c[200] = { '\0' };

or just like

char c[200] = "";

;

The second one is you access memory beyond the the allocated array in the function ft_strdup.

x[i+1] = '\0';

you have to write

x[j] = '\0';

And you have to check the return value of the function.

Pay attention to that in C++ you should use the operators new and delete instead of the C functions malloc and free. And instead of dynamically created character arrays to store strings you should use the standard C++ class std::string.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335