tags:

views:

182

answers:

3

I've seen a lot of questions on that on StackOverflow, but reading the answers did not clear that up for me, probably because I'm a total newbie in C programming. Here's the code:

#include <stdio.h>

char* squeeze(char s[], char c);

main()
{
  printf("%s", squeeze("hello", 'o'));
}

char* squeeze(char s[], char c)
{
  int i, j;

  for(i = j = 0; s[i] != '\0'; i++)
    if(s[i] != c)
      s[j++] = s[i];
    s[j] = '\0';

  return s;
}

It compiles and I get segmentation fault when I run it. I've read this faq about about returning arrays and tried the 'static' technique that is suggested there, but still could not get the program working. Could anyone point out exactly what's wrong with it and what should I be paying attention in the future?

+3  A: 

The problem is that the constant char array "hello" may not correctly be modified by the function to which it was passed. So, just make sure you're passing a non-constant array (for example by making a local array to be passed, as long as the result is not needed outside of squeeze's caller):

int main()
{
  char xxx[] = "hello";
  printf("%s", squeeze(xxx, 'o'));

  return 0;
}

You'd expect that such a constant could only be passed to a const argument (so that the compiler itself could tell you what you're doing wrong), but, alas, that's not what the C standard mandates (presumably for reasons of backwards compatibility with historical code).

Alex Martelli
There's nothing temporary about it, the string is stored in "static" memory.
dash-tom-bang
Good point (and by wording on my part, let me rephrase).
Alex Martelli
+6  A: 

The 1st argument passed to the squeeze function is a read-only string literal "hello", which you are trying to modify.

Instead pass it a modifiable char array:

char str[] = "hello";
printf("%s", squeeze(str, 'o'));
codaddict
One could also invoke the principle of least surprise to suggest making a copy of the string, instead. If I'm passing a char* into a function that returns char*, I may not expect that it's modifying the array in-place. (API designers are often sloppy in whether they use _const_.)
Nicholas Knight
+3  A: 

This is trying to modify non-modifiable data.

"hello" is a constant string, stored in memory somewhere. What you're trying to do, then, is change it, and that's generally not allowed. I don't see what you mean by "static", but what you want would be something like...

int main()
{
  char hello_str[16];
  strcpy(hello_str, "hello");
  printf("%s", squeeze(hello_str, 'o'));
}
dash-tom-bang