2

I am getting segmentation fault in the below while loop.

int main() {
    register char *str = "Hello World";
    char *ans;
    ans = test(str);
    if(!ans)
        return 1;
    free(ans);
    return 0;
}
char *test(char *str) {

         char *str1 ;
         char *str2;
         char *str3;
         str1 = malloc(strlen(str) + 5);
         str2 = str;
         str3 = str1;
         *str3++ = '\b';
         *str3++ = '\b';
         while(*str2)
             *str3++ = *str2++;
         *str3++ = '\f';
         *str3++ = '\f';
         *str3 = '\0';
         return (str1);
}

I think I am getting segmentation fault in while loop. Could you please suggest why? I am calling this as char *ans = test(string) where string is register char *string. Let us say, I have hello world in the string. My intention is to return \b\bHello World\f\f from test().

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Pushpa
  • 21
  • 3
  • How are you calling it, what is it supposed to do, and why isn't it indented? – Ry- Aug 10 '16 at 04:58
  • Please post a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – R Sahu Aug 10 '16 at 05:07
  • The code as written works fine with a program like this: `int main(void) { char *t1 = test("Hello World"); if (t1 != 0) printf("[%s]\n", t1); free(t1); return 0; }` — assuming you include the mighty trio of headers (``, `` and ``) — and [`valgrind`](http://valgrind.org/) gives it a clean bill of health. So either you've fixed the code while getting it clean enough to compile, or your problem is elsewhere. IMNSHO, of course. – Jonathan Leffler Aug 10 '16 at 05:10
  • When i compile with normal gcc it works fine. This issue is seen with x86 64 bit compiler. – Pushpa Aug 10 '16 at 05:12
  • Are you including the headers? I tested on Mac OS X 10.11.6 with GCC 6.1.0 with a 64-bit compilation (an Intel x86_64 platform). You could run into problems if you didn't include the headers and the compiler was too old and/or assumed that `malloc()` returned an `int` because it didn't have a declaration. – Jonathan Leffler Aug 10 '16 at 05:13
  • Yes. I have included headers. I see that "\b\b" gets copied to str3. after that it crashes. – Pushpa Aug 10 '16 at 05:15
  • How exactly do you call `test()`? Make your code complete: we can't debug the non-working code if you don't provide the non-working code. That sounds as if you're passing an improper pointer as the argument to the `test()` function. It doesn't sound as if `malloc()` is failing, though for maximum safety (or production code) you should check for that before using the returned value. – Jonathan Leffler Aug 10 '16 at 05:17
  • Thanks Jonathan. I am passing register char * to the function. Is it because of that ? – Pushpa Aug 10 '16 at 05:25
  • 2
    The problem is that you didn't declare `test` before you used it, so the compiler assumes it returns an `int` when it is called, but that doesn't work properly on 64-bit (because `sizeof(int) != sizeof(char *)` on 64-bit, but it coincidentally 'works' on 32-bit because there `sizeof(int) == sizeof(char *)`. But the compiler should be shrieking at you. How many warnings are you ignoring? Which version of GCC are you actually using, on which platform. At minimum, add `-std=c11 -Wall -Wextra`; I add other options to that list before I'll risk posting code here on SO. – Jonathan Leffler Aug 10 '16 at 05:26
  • Also note that there is no point in using `register` in modern C code. The compiler basically ignores it (though it will complain if you try to take the address of a `register` variable). [C++17](http://stackoverflow.com/questions/1549685/how-can-i-use-a-variable-as-a-variable-name-in-perl) is removing `register` as an active keyword, though reserving it for future (re)use. – Jonathan Leffler Aug 10 '16 at 05:31
  • 3
    Note that at this stage of your C programming career, if the compiler generates a warning, treat it as an error that must be fixed before running the program. In fact, if you've got any sense, you'll use that as a guideline for the indefinite future. I've only been coding in C for 30+ years, and if there's a warning, I make sure I fully understand what it means and why I'm getting it before ignoring it. I'll go to considerable lengths to make sure that my code compiles with zero warnings under stringent options and with `-Werror` (which forces GCC to treat warnings as errors). – Jonathan Leffler Aug 10 '16 at 05:35

1 Answers1

0

Your issue is that you didn't declare your function test properly. You have to declare every function that is used before it is used, be it by putting the actual function above or writing a function declaration.

As soon as you do that, your code works:

#include <stdio.h>
char *test (char *str); // this is the function declaration
int main(void) {
    register char *str = "Hello World";
    char *ans;
    ans = test(str);
    if(!ans)
        return 1;
    free(ans);
    return 0;
}
char *test(char *str) {

         char *str1 ;
         char *str2;
         char *str3;
         str1 = malloc(strlen(str) + 5);
         str2 = str;
         str3 = str1;
         *str3++ = '\b';
         *str3++ = '\b';
         while(*str2)
             *str3++ = *str2++;
         *str3++ = '\f';
         *str3++ = '\f';
         *str3 = '\0';
         return (str1);
}

Demo: https://ideone.com/HIXyMs

Magisch
  • 7,312
  • 9
  • 36
  • 52