1

The following code aborts with a segmentation fault error at the commented line. The line is intended to do a simple replacement of one character.

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

int num(char zf[], int n) {
    int i;

    for (i = 0; i < n; i++) {
        // assignment = seg fault
        if (zf[i] == ',') zf[i] = '.';

        if (!isdigit(zf[i]) && zf[i] != '+' && zf[i] != '-' && zf[i] != '.') {
            return 0;
        }
    }

    return 1;
}

int main(void) {
    if (num("-3+3,0", 6)) {
        printf("valid\n");
    } else {
        printf("not valid\n");
    }

    return 0;
}

I'm looking for an explenation why there's an error and what the solution is to this? strncpy? The parameters and datatypes of the function num are not to be changed.

pori
  • 73
  • 7
  • 7
    Modifying a string literal is undefined behaviour. Here's a question with a similar problem (and there are many more): http://stackoverflow.com/questions/943312/segmentation-fault-char-pointer?rq=1 – chris Jul 23 '14 at 19:10
  • 2
    it is [undefined behavior to modify a string literal](http://stackoverflow.com/questions/19372952/modifying-a-char-const-string) – Shafik Yaghmour Jul 23 '14 at 19:10
  • Yep, string literals are constants. – Fiddling Bits Jul 23 '14 at 19:11
  • Funny, this is a mock exam and "num(char zf[], int n)" is provided by the teacher. Not sure how to solve this at all. – pori Jul 23 '14 at 19:15
  • 1
    @thpetrus, Don't give it a string literal. Give it something it can actually modify. – chris Jul 23 '14 at 19:16
  • @ShafikYaghmour, Hmm, interesting. I've always had the notion that if the other question can answer this one, it should be a dupe, even if the two questions are not the same. The way I see it, having a good answer there that answers the current question definitely helps, and then any new answer that comes up basically repeats that one. Still, considering I participated in that question, it would be nice to get notification that it has a meta post. I never know what's going on in meta. – chris Jul 23 '14 at 19:18
  • @chris I was pinged which is how I knew but I agree a notification would be nice. The question was reopened so I answered before someone else could make another hash of it. – Shafik Yaghmour Jul 24 '14 at 02:43
  • The literal: "-3+3,0" will be in the .const section of the link. That is a nonwritable section. – user3629249 Jul 24 '14 at 05:25

3 Answers3

6

String literals are compiled into the program and stored somewhere in the binary as an array of bytes. You can try the strings command in Linux to find string literals in a binary.

The string constants most likely exist in read only parts of programs and that is why it was made undefined behavior to modify them. A segmentation fault happens when you try to access or modify parts of memory that should not be accessed or modified.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
AxelOmega
  • 974
  • 10
  • 18
1

Though in C string literals have type of non-constant character arrays nevertheless the C Standard does not allow to change them.

4 The same considerations apply to each element of the sequence in a string literal as if it were in an integer character constant

If a program attempts to modify a string literal then its behaviour is undefined.

You should defined main the following way

int main(void) {
    char s[] = "-3+3,0";

    if (num(s, sizeof( s ) - 1 )) {
        printf("valid\n");
    } else {
        printf("not valid\n");
    }
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Here in if (num("-3+3,0", 6)) , "-3+3,0" is stored in read-only memory. So modifiying it, will result in segmentation fault.

Use an array so that "-3+3,0" is stored in stack. Then we can modify the values.

rohit
  • 198
  • 1
  • 1
  • 7