2

When I run this I get a segmentation fault??

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

static char* exe;

void usage(void) {
    printf("Usage: %s <number of integers>\n", exe);
}

int main(int argc, char** argv) {
    //This program reads in n integers and outputs them/
    //in reverse order. However, for some odd reason, I/
    //am getting an error when I run it with no command/
    //line arguments. It is supposed to display helpful/
    //usage information out, but instead it segfaults??/
    exe = malloc(50 * sizeof(*exe));
    strncpy(exe, argv[0], 49);

    if(argc != 2) {
        usage();
        exit(0);
    }

    int n = atoi(argv[1]);
    int* numbers = malloc(n * sizeof(*numbers));

    int i;
    for(i = 0; i < n; i++) {
        scanf("%d\n", &numbers[i]);
    }

    for(i = 9; i >= 0; i--) {
        printf("%d:\t%d\n", 10 - i, numbers[i]);
    }

    free(numbers);
    free(exe);
    return 0;
}
C0deH4cker
  • 3,959
  • 1
  • 24
  • 35
  • Where does a debugger say that the segfault is occurring? What inputs are you giving this program? – templatetypedef May 23 '13 at 00:31
  • The line with `strncpy` causes a segfault. I am running it like `./numbers 10` – C0deH4cker May 23 '13 at 00:32
  • possible duplicate of [What does the C ??!??! operator do?!](http://stackoverflow.com/questions/7825055/what-does-the-c-operator-do) – Daniel Fischer May 23 '13 at 00:42
  • Possible duplicate of [What does the C ??!??! operator do?](https://stackoverflow.com/questions/7825055/what-does-the-c-operator-do) – VLL Jun 26 '19 at 12:33

3 Answers3

7

It's because the ??/ is a trigraph that turns into \, causing your exe = malloc... line to turn into part of the comment. Thus, exe is still NULL, and crashes when you dereference it.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • +1 Um, wow. I can't tell if this is a legitimate question or if we're just getting trolled. – templatetypedef May 23 '13 at 00:37
  • My money is on the OP just having read another of the trigraph questions where that specifically was mentioned. – Daniel Fischer May 23 '13 at 00:38
  • Really nice one. Totally missed the trigraph. – Ram Rajamony May 23 '13 at 00:40
  • Haha nice, was wondering how many people knew about trigraphs. Surprised someone posted the correct answer less than 10 minutes after I asked this. And yes, I did know about the trigraph beforehand (look at the perfectly aligned comment :P), but it is definitely good to know about trigraphs and be careful of them. Congrats, sir, you got my upvote and accept. – C0deH4cker May 23 '13 at 00:42
  • [Here it was](http://stackoverflow.com/questions/16662276/meaning-of-in-c-code#comment23973886_16662276) – Daniel Fischer May 23 '13 at 00:45
  • @C, you'd be surprised how many different aspects of C and C++ I've learned from browsing SO. They're all here somewhere. – chris May 23 '13 at 00:46
  • No, I didn't read any other question here lol. It was mentioned on my Twitter timeline this morning by @0xabad1dea. Plus, I already knew about trigraphs from the IOCCC. Just having a little education fun :P – C0deH4cker May 23 '13 at 00:46
  • 1
    The question may have been slightly more puzzling if you did not include the whole program, but just the two lines of code preceded by the funny comment. I cut and pasted the whole program, and GCC warns about trigraphs by default. – jxh May 23 '13 at 00:49
  • Yeah, I had to throw in a `-trigraphs` option to clang just to get the segfault. Without that it works fine. Some compilers will parse trigraphs by default though. They are converted in comments because, unlike digraphs, trigraphs are parsed by the preprocessor instead of the tokenizer. – C0deH4cker May 23 '13 at 00:55
0

The variable argv[0] holds a pointer to the name of the program you are running. Your program is trying to read either 49 chars starting from this pointer, or the NULL, whichever comes first. In your case, you are probably moving to a new page which you don't have rights to access.

Ram Rajamony
  • 1,717
  • 15
  • 17
0

You need to make sure your exe string has a NULL terminator after you strncpy.

Try adding this line after the strncpy:

    exe[49] = '\0';
MatthewD
  • 2,509
  • 2
  • 23
  • 27
  • `strncpy` adds a NULL terminator... Plus, the `strncpy` function itself causes the segfault. – C0deH4cker May 23 '13 at 00:36
  • strncpy only adds a NULL terminator if there is one in the first `n` (49 in your case) characters. Otherwise, it won't. – MatthewD May 23 '13 at 10:06