Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: Stack around the variable 'string' was corrupted

Tags:

c

I've a small problem with the code below. It is a simple program which reads in 2 arrays of char and an int. Then it stores all the content into another string and prints it out.

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

int main ()

{
    char string [50];
    char first [11]; 
    char last [16];
    int age = 0;


    printf("Please type in your first name: ");
        scanf("%s", first); 

    printf("Please type in your last name: ");
        scanf("%s", last); 

    printf("Please type in your age: ");
        scanf("%d", &age); 

    sprintf(string, "Your name is %s %s and you are %d years old.", first, last, age);
        puts(string);

    getchar();
    getchar();

    return 0;
}

Now the program is running fine, but when i close it, i get the following error: Run-Time Check Failure #2 - Stack around the variable 'string' was corrupted. That's a bit confusing and i can't figure out where the problem is. I would be thankful for any advice.

like image 703
Ordo Avatar asked Jan 10 '11 07:01

Ordo


4 Answers

You are writing more characters into 'string' than it has room allocated for (i.e. more than 50)

There are 37 characters in "Your name is %s %s and you are %d years old." BEFORE you add the values for first, last and age. That leaves just 13 chars for all three variables. So it spills over into the other vars declared after your variable 'string' on the stack.

As Jon mentioned, it is best practice to use the functions that limit how much they write (the 'n' variants), otherwise these can be sources of bufferoverrun exploits.

BTW 'string' is a very poor name for a variable.

like image 138
Mitch Wheat Avatar answered Nov 19 '22 19:11

Mitch Wheat


Aside from anything else, you've allowed for a first name of up to 10 characters and a last name of up to 15 characters. If those limits are reached (but not exceeded) and the age is a two digit number, that will take 66 characters - so you would have to declare string to be an array of 67 characters to cope (to include the null terminator).

Beyond that, you should be using functions or format strings which allow you to limit the size of the input - currently if someone enters a first name of longer than 10 characters (etc) you'll trample over other bits of memory. It's been a while since I've written any C, but using format strings of "%10s" and "%15s" may help in this respect - or use fgets.

Likewise, I would suggest using snprintf (or snprintf_s if it's available to you) instead of sprintf to avoid the overrunning-output problem. Use the return values of all of these methods to detect errors, too :)

like image 28
Jon Skeet Avatar answered Nov 19 '22 20:11

Jon Skeet


I'd guess it's something to do with the fact that the length of the string array is 50 chars, you have in the sprintf 37 (if I counted right) plus then up to 11 for first and another 16 for last, plus maybe 2 or 3 for age. That adds up to more than 50. Everything works ok, but you're very likely overwriting beyond the end of the 50 chars allocated. That will 'work', but corrupt the stack, as you have observed.

like image 36
martin clayton Avatar answered Nov 19 '22 18:11

martin clayton


You can limit the amount of chars scanf reads with

scanf("%9s", foo)

which will read at most 9 characters, then append a NUL, which is suitable for a buffer of size 10.

like image 23
Alex Budovski Avatar answered Nov 19 '22 18:11

Alex Budovski