1

I am running a program in C using a GetString function (not from the CS50 library). When I run the program I get a segmentation fault error. In GDB, when I backtrace it tells me:

Program received signal SIGSEGV, Segmentation fault. __strlen_sse2_bsf () at ../sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S:51 51 movdqu (%edi), %xmm1

I believe it has to do with strlen.

The only time I use strlen is:

string s = GetString();
int stringlength = strlen(s);

When I change strlen to sizeof the error disappears.

What is wrong with my code?

Documentation of GetString:

/*
 * Reads a line of text from standard input and returns it as a 
 * string (char *), sans trailing newline character.  (Ergo, if
 * user inputs only "\n", returns "" not NULL.)  Returns NULL
 * upon error or no input whatsoever (i.e., just EOF).  Leading
 * and trailing whitespace is not ignored.  Stores string on heap
 * (via malloc); memory must be freed by caller to avoid leak.
 */

string GetString(void) {
// growable buffer for chars
string buffer = NULL;

// capacity of buffer
unsigned int capacity = 0;

// number of chars actually in buffer
unsigned int n = 0;

// character read or EOF
int c;

// iteratively get chars from standard input
while ((c = fgetc(stdin)) != '\n' && c != EOF)
{
    // grow buffer if necessary
    if (n + 1 > capacity)
    {
        // determine new capacity: start at 32 then double
        if (capacity == 0)
            capacity = 32;
        else if (capacity <= (UINT_MAX / 2))
            capacity *= 2;
        else
        {
            free(buffer);
            return NULL;
        }

        // extend buffer's capacity
        string temp = realloc(buffer, capacity * sizeof(char));
        if (temp == NULL)
        {
            free(buffer);
            return NULL;
        }
        buffer = temp;
    }

    // append current character to buffer
    buffer[n++] = c;
}

// return NULL if user provided no input
if (n == 0 && c == EOF)
    return NULL;

// minimize buffer
string minimal = malloc((n + 1) * sizeof(char));
strncpy(minimal, buffer, n);
free(buffer);

// terminate string
minimal[n] = '\0';

// return string
return minimal;
}
1
  • As far as I know, segmentation fault arises when you try to access a NULL/empty memory space. – sinister Jun 9 '14 at 7:11
3

The description of the GetString() function clearly states that it can return NULL on an error or an EOF.

If you pass the return value to strlen() without checking, your program will crash.

string s = GetString();
int stringlength = 0;

if (s != 0)
    stringlength = strlen(s);

This at least won't crash.

I also observe that the code fragment:

// minimize buffer
string minimal = malloc((n + 1) * sizeof(char));
strncpy(minimal, buffer, n);
free(buffer);

could be better, and more simply, written as:

string minimal = realloc(buffer, n + 1);

to shrink the allocation to the correct size.

1
  • checking the string for null before I use strlen solved my problem. Thank you – KlausCode Jun 9 '14 at 7:28
1

Two things.

One. Not sure why you say "not in the CS50 library" when you then pasted in the exact function that is in the CS50 library.

Two. You'd generally get a segfault with strlen if the string doesn't actually exist (it's NULL) at the time you call strlen(). Are you actually entering a string in the terminal in response to your call to GetString()?

Can you show us a bit more of your code, if it's not from your solution to an actual pset? It's pretty hard to diagnose just as is.

Brenda.

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .