Hello, I'm trying to take a C array of char's and trying to take all of the spaces out of it. Yet I keep running into a segmentation fault. Can anyone help me here?

#include <stdio.h>
#include <stdlib.h>

int strlen(char* Str) {
    int toret=0;
    int i=0;

    char tmp = ' ';

    while (tmp != '\0') {
        toret += 1;
        tmp = Str[i];
        i++;
    }

    return toret;
}

char* deblank(char* OrgStr) {

    char* chr1 = OrgStr;
    char* chr2;

    int len = strlen(OrgStr);

    char* NewStr = (char*) malloc(len + 1);

    int i=0;
    int j=0;

    while (len >= 0) {
        *chr1 = OrgStr[j];
        if (*chr1 != ' ') {
            NewStr[i] = *chr1;
            i++;
        }
        j++;
        len--;
    }

    NewStr[i] = '\0';
    return NewStr;
}

int main(void) {

    printf("TEST\n");

    char* test = "Hello there";
    char* b = deblank(test);
    
    printf("%s\n%s\n", test, b);

    return 0;
}

Dani AI

Generated

The crash comes from a few separate bugs in the posted code: the custom strlen is implemented incorrectly (it overcounts and reads out of bounds), the deblank routine writes into OrgStr (which in char *test = "Hello there"; is a string literal and commonly placed in read-only memory), and the loop/indices create off-by-one reads. was right to point out using the standard strlen (and to avoid redefining it), and was right that writing to a literal causes a segfault.

A safe, simple approach is to treat the input as const char *, count how many non-space characters, allocate exactly that much space, copy only the kept characters, and return the new buffer. Free the returned pointer when done. Example:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

char *deblank(const char *src) {
    if (!src) return NULL;
    size_t keep = 0;
    for (const char *p = src; *p; ++p)
        if (*p != ' ')
            ++keep;
    char *dst = malloc(keep + 1);
    if (!dst) return NULL;
    char *q = dst;
    for (const char *p = src; *p; ++p)
        if (*p != ' ')
            *q++ = *p;
    *q = '\0';
    return dst;
}

If you prefer in-place modification (no allocation), copy into a writable array, e.g. a char buf[N] populated with strncpy or strcpy, then perform the same compressing loop writing into the same buffer.

Quick checklist:

  • Do not redefine strlen (in C use <string.h>; in C++ <cstring>).
  • Never write to string literals—use writable arrays if you must edit in place.
  • Use size_t for lengths and check malloc results.
  • To drop all whitespace (tabs, newlines) use isspace((unsigned char)*p) from <ctype.h>.
  • Compile with warnings (-Wall -Wextra) and run under Valgrind or ASan to catch out-of-bounds and invalid writes.

Recommended Answers

All 6 Replies

  1. Why did you write your own strlen function?
  2. Should your strlen function return the same value as cstring's strlen function?
  3. If so, you need to rewrite strlen because it gives bad results (i.e. "a" will return 2, not 1).

1. I couldn't find which header strlen is in :/
2. It should. But I'm not sure what it's supposed to return.
3. Well in that case, I'll just have it return -1 than what it usually does.

EDIT:
And it still says segmentation fault

1. I couldn't find which header strlen is in :/
2. It should. But I'm not sure what it's supposed to return.
3. Well in that case, I'll just have it return -1 than what it usually does.

EDIT:
And it still says segmentation fault

It's defined in cstring.


Returns the length of str.

The length of a C string is determined by the terminating null-character: A C string is as long as the amount of characters between the beginning of the string and the terminating null character.

I can't guarantee that your strlen will ALWAYS return one less than the real strlen. I didn't look at the code. I just tested it with "a". In that particular case, your strlen returned one greater than it should have.

For debugging purposes, use the real strlen function above and see if that gets rid of the seg fault.

Your problem is probably that your program is trying to remove blanks in place, but on line 50 you're calling it with a string literal as its arguments. Compilers are permitted to write-protect the contents of string literals, and many of them do these days.

As a quick check of what your implementation does, try the following:

int main()
{
    char* p = "foo";
    *p = ' ';
}

and see what it does.

Yes, it said "segmentation fault" yet again. What do I do with this?

What do I do with this?

Don't use string literals. Use character arrays and use strcpy to put a string in them.

Replace code like this:

char* test = "Hello there";

with something like this:

char test[20]; // 20 is just a number bigger than the length of the string.
strcpy(test, "Hello there");
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.