0

I am working on a program to ask a user to enter a word and the number of letters the user wants copied from that word. The program works when I use Compile Online, but when I run the program in Micrsoft Visual Studio, the program freezes after I enter the word I want copied. I ran the debugger and found the error shown below. I take it, from googling, that I am writing past the amount of memory set aside for my array? Should I use malloc to fix that? Posted below are the errors and the code (link to original stackoverflow thread.

Exception thrown at 0x0FFB0BA0 (ucrtbased.dll) in lab1113problem7.exe: 0xC0000005: Access violation writing location 0x00B80000.

Unhandled exception at 0xFEFEFEFE in lab1113problem7.exe: 0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000003).

The program '[7196] lab1113problem7.exe' has exited with code 0 (0x0).

Program:

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

char *copywords(char *dest, const char *source, size_t n);

int main(void) {
    char words[50];
    char newwords[50];
    int num;

    for (;;) {
        printf("Type a word, or type 'quit' to quit: ");
        if (scanf("%49s", words) != 1) {
            printf("Invalid input!\n");
            return 0; 
        }
        if (!strcmp(words, "quit")) {
            printf("Good bye!\n");
            return 0; 
        }
        printf("Type the # of chars to copy: ");
         if (scanf("%d", &num) != 1) {
            printf("Invalid input!\n");
            return 0; 
        }
        copywords(newwords, words, num);
        printf("The word was %s\n", words);
        printf("and the copied word is %s\n", newwords);
    }
}

char *copywords(char *dest, const char *source, size_t n) {
    size_t i;
    for (i = 0; i < n && source[i] != '\0'; i++) {
        dest[i] = source[i];
    }
    dest[i] = '\0';
    return dest;
}
Community
  • 1
  • 1
Markovnikov
  • 41
  • 4
  • 13
  • Use the debugger more effectively to help you find the problem. For starters which line of code exactly does it crash on. The debugger tells you that . And use the debugger to check the value of `num`. Then continuing continue stepping through the program line by line. – kaylum Nov 28 '16 at 23:04
  • 1
    I haven't found any problems. But are you absolutely sure that this is the actual code that you are running? For example, if you add `printf("Yes, this is the actual code!\n");` as the first statement of `main` and then run the program, will you see that output, and will the program still not work? – Thomas Padron-McCarthy Nov 28 '16 at 23:07
  • @kaylum The debugger stops and throws the exception out as soon as I enter a word. – Markovnikov Nov 28 '16 at 23:24
  • @Markovnikov Well yeah, you knew that already. Also, the debugger does not throw an exception, your program throws an exception that the debugger tells you about. Also, from which part of your code did the exception get thrown? Look at the "call stack" window/pane/area. – user253751 Nov 28 '16 at 23:41
  • @Markovnikov Yes, but you can get what is called a "stack trace" from the debugger. That tells you exactly which line of code triggered the crash. Clearly you have not learnt to use the debugger effectively. Please do so. It will be time well spent. – kaylum Nov 28 '16 at 23:44
  • @immibis it looks like the exception gets thrown at line 14 or line 1. Am I not allocating enough memory for the array? The debugger also freezes up when I tried to stop debugging. – Markovnikov Nov 29 '16 at 00:02
  • How big are the words you pass in? Also, not sure if scanf will zero terminate your string for you on too big - I'd add a hard-coded \0 char to the end of the array just in case. – Michael Dorgan Nov 29 '16 at 00:22
  • Also putting a limiter into your string copy loop for size or a print right before it overflows the array could help you as well. – Michael Dorgan Nov 29 '16 at 00:23
  • @MichaelDorgan How do I add a limiter? – Markovnikov Nov 29 '16 at 00:24
  • But that isn't inside the loop where the overrun may occur. Try inside right before each character is copied (think of it as debug code.) – Michael Dorgan Nov 29 '16 at 00:25
  • for limiting, in your for loop, check for `i < MAX_ARRAY_SIZE` and define your array sizes to this. It's the equivalent to strncpy() basically. – Michael Dorgan Nov 29 '16 at 00:27
  • I added \0 inside the loop and it still did not work. I'm not sure how to do the MAX_ARRAY_SIZE as I am new to c. – Markovnikov Nov 29 '16 at 00:39

1 Answers1

0

Some debug code to make sure things are working as intended for your strings:

// Place this at the top of your file, after your `#include` statements 
// and use it in place of the 50s in your array defines.
#define MAX_ARRAY_SIZE 50

char *copywords(char *dest, const char *source, size_t n) {
    size_t i;
    for (i = 0; i < n && source[i] != '\0'; i++) {
        if(i >= MAX_ARRAY_SIZE)
        {
            printf("I just blew up memory at %i\n", %i);
        }
        dest[i] = source[i];
    }
    dest[i] = '\0';
    return dest;
}

Note: you can check the array size each iteration instead within the for loop to be sure that you haven't overrun your buffers.

Not a direct answer, but something to try and easier than using comments. If the printf is triggered, you know bad has happened...

Even better, because you pass in the size as n, you can check array size before the loop every starts and handle bad data immediately.

char *copywords(char *dest, const char *source, size_t n) {
    if(n >= MAX_ARRAY_SIZE) 
    {
        printf("Array will overflow by %d bytes- truncating\n", n - MAX_ARRAY_SIZE);
        n = MAX_ARRAY_SIZE;
    }
Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
  • Thank you for your help. I tried both debug codes and MSVS will not let them execute - the program will not let me get past entering a word and the debugger constantly asks "pass exception on to program being debugged?" and no matter if I say yes or no the same error as in my original post appears. I just flat out do not know what is wrong nor do I know how to fix it. – Markovnikov Nov 29 '16 at 00:52
  • ok, error is before this code is called then. Place break points in your debugger before each line or single-step through the code. (Or, if you don't know how ot do this, place a printf() statement after each line of code in your main loop that contains a "I am here\n" type message and see how far it gets. – Michael Dorgan Nov 29 '16 at 00:53
  • I added print statements to the code. It worked fine until after I entered a word. One warning that the complier is giving is "'scanf_s' not enough arguments passed for format string" - should I use something besides scanf to get the string? Would getchar or fgets work? If so how do I format those to work with the code to quit? – Markovnikov Nov 29 '16 at 01:25
  • @Markovnikov Why is MSVC talking about scanf_s when you're using scanf not scanf_s? – user253751 Nov 29 '16 at 02:33
  • Microsoft Visual Studio forces programmers to use scanf_s as scanf is seen as not being secure. – Markovnikov Nov 29 '16 at 06:56
  • @Markovnikov: So are you using scanf or sscanf_s? The code you have shown has scanf, but the warning that you told us about has scanf_s? Which one is it? If you try to call to scanf_s with the same arguments as scanf, yes, that can cause the program to crash. _Provide the actual code that you are running!_ – Thomas Padron-McCarthy Dec 03 '16 at 15:56