Segfault with strcmp
Asked Answered
T

2

10

I am using strcmp in following ways

  1. Passing char[] array names
  2. Passing pointers to string literals but, the second result in seg fault. even though i have confirmed that pointers point to correct string literals, i am confused as to why i am getting seg fault.. Here is the code:-

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char const *args[])
    {
      char firstName[strlen(*++args)];
      strcpy(firstName, *args);
      char lastName[strlen(*++args)];
      strcpy(lastName, *args);
      printf("%s\t%s\n", firstName, lastName);
    
      printf("%d\n", strcmp(firstName, lastName));// this works
    
      printf("%d\n", strcmp(*(--args),*(++args)));//this gives me a seg fault
    
      return EXIT_SUCCESS;
    }
    

I am saving it as str.c and when i compile it, first i get following warning:

[Neutron@Discovery examples]$ gcc -Wall str.c -o str

str.c: In function ‘main’:
str.c:15: warning: operation on ‘args’ may be undefined

finally running it, gives a seg fault as shown below

[Neutron@Discovery examples]$ ./str Jimmy Neutron


Jimmy   Neutron

-4

Segmentation fault (core dumped)
Tenderloin answered 10/6, 2011 at 4:15 Comment(1)
Voting "too localised" on this makes no sense at all. It's arguably a duplicate of #7877758 since the real question is "what does this warning mean?" but too localised is just perverse: unhelpful and missing the point.Sosna
D
14

Don't use -- and ++ when you pass the same variable to the same function twice as two different parameters.

Instead of printf("%d\n", strcmp(*(--args),*(++args)));

do

char *first = *(--args);
char *second = *(++args);
printf("%d\n", strcmp(first,second));

Still not really readable (better use indexes and check against argc for validity), but at least you don't change the value and evaluate multiple times it at the same sequence point.

Divot answered 10/6, 2011 at 4:18 Comment(6)
@Jimm: C does not guarantee any order of evaluation. It's usually not left-to-right. Modifying a variable more than once in the same statement is undefined behaviour.Anthotaxy
@Jimm, yes, but you're changing the values and evaluating them at the same time, it's undefined behavior.Divot
Can you please be kind enough to point me to some gcc documentation or some official source, which explains why i cannot access same variable twice in a single function call. Please keep in mind that ++args and --args is simply traversing the memory addresses. It is not modifying anything.Tenderloin
It's modifying the pointer variable args, and you cannot modify it more than once between sequence points.Adeleadelheid
Thank you for bringing sequence point to my knowledge. It was the missing link, that was making me hard to understand littleadv's comments. After looking on wikipedia for sequence points, en.wikipedia.org/wiki/Sequence_point, it actually tells the exact clause in it's referencesTenderloin
Read section 3 of the comp.lang.c FAQ. Then read the rest of it.Hildebrand
A
6

In addition to what littleadv's post says, your buffers are one character too short (it didn't leave any space for the null-terminator). Thus, your strcpy causes a buffer overflow.

Anthotaxy answered 10/6, 2011 at 4:19 Comment(2)
Odd, even though strcmp, is an unrestricted string function, the above works fine with character arrays WITHOUT NULL character. It is only when i do strcmp with pointers, that i get seg fault.Tenderloin
@Jimm: It's still undefined behaviour, as buffer overflow still happened (it will write a null terminator; it just will do so outside your buffer's bounds). You're in this case lucky that the buffer overflow didn't kill your program sooner.Anthotaxy

© 2022 - 2024 — McMap. All rights reserved.