-2

Curious about what is going wrong with this strcpy.

int main(void){
    char *history[10];
    for(int i = 0; i < 10; i++){
        history[i] = NULL;
    }
    char line[80];
    fgets(line,80,stdin); 
    strcpy(history[0],line); //This line segfaults
}
MoStack
  • 29
  • 2
  • 3
  • 1
    You are doing `strcpy(NULL, line)`. – Ken Y-N Oct 18 '17 at 03:50
  • You forgot to assign storage to `history[0]`, so of course it blows up. You can use `history[0] = strdup(line)` instead. – Tom Karzes Oct 18 '17 at 03:51
  • modify the definition of history by `char history[10]`, and use `strcpy(history, line)`, since `char *` declares that the element of history is a pointer, not a character. – wt.cc Oct 18 '17 at 03:53

2 Answers2

4

You've created an array of NULL pointers. You then tried to copy characters onto NULL. That's a no-no.

EDIT: Your program could be optimized to this:

void main() {
   char line[80];
   fgets(line,80,stdin); 
}

Your history array is never used to generate any output. So, while others have pointed out you need to allocate memory, technically, you could simply do this:

history[0] = line;

That will be a valid pointer up until the line goes out of scope, which is when history goes out of scope so it won't matter.

Garr Godfrey
  • 8,257
  • 2
  • 25
  • 23
1

You need to allocate memory for history[0]. As history[0] is assigned NULL referencing it or writing to it will/may cause segfault.

something like

//this will create memory for 100 chars
history[0] = malloc(sizeof(char) * 100); 
strcpy(history[0],line);

Or

//shortcut for both - this allocate new memory and returns pointer.
history[0] = strdup(line);
Rohan
  • 52,392
  • 12
  • 90
  • 87
  • What is the best thing to initialize the history to? Also thank you for the help – MoStack Oct 18 '17 at 03:52
  • @MoStack, initialize to NULL is fine, but when you want to use it to store chars you should allocate memory to it. – Rohan Oct 18 '17 at 03:53
  • This answer would be fantastic, if only you replaced "will/may cause segfault" to "may behave erratically". The reason you can't say it "will cause a segfault" is that gives a definition; that defines the outcome, where-as in standard C the outcome is considered *undefined*. Other things could happen, too. Notable examples of *undefined behaviour* which often don't cause segfaults include: vulnerabilities such as buffer overflows and format string vulns, race conditions (multiple threads accessing the same resource at the same time), signed integer overflow and... this, if run on some devices. – autistic Oct 18 '17 at 04:21