堆栈溢出问题:最大容量2,077,072

时间:2016-03-12 05:04:45

标签: c stack-overflow

基本上,我写了一个相当小的随机字符生成器,​​用户可以在其中选择字符串的长度。该程序可以成功创建一个长度为2,077,072的字符串,但崩溃时堆栈溢出的数量大于该值。

这个数字似乎相当随意,因为log2(thatNumber)等于20.9左右。它太小,不能超过两个mebibytes,16位和32位大小都不远。在所有地方,为什么要打破这个?

该程序至少执行"处理..."标记

我的代码:

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

char getChar(int, int, int);

//MAXIMUM PASSWORD LENGTH: 2,077,072
//2,077,073 gives stack overflow

int main(int argc, char **argv) {
    if(argc != 5) {
        printf("Incorrect number of arguments.\n Usage: PassGenII arg1 arg2 arg3 arg4\n");
        printf("arg1: Password length\narg2: Use lowercase characters? 0 or 1\narg3 Use uppercase characters? 0 or 1\narg4: Use numeric characters? 0 or 1\n");
        return 0;
    } else {
        int passLength;
        int lower;
        int upper;
        int numeric;

        passLength = atoi(argv[1]);
        lower = atoi(argv[2]);
        upper = atoi(argv[3]);
        numeric = atoi(argv[4]);

        printf("\nPassword length: %d\n", passLength);
        printf("lowercase: %d\n", lower);
        printf("uppercase: %d\n", upper);
        printf("numerals: %d\n", numeric);
        printf("\nProcessing...");
        char pass[passLength];

        srand(time(NULL));
        int i;
        for(i = 0; i < passLength; i++) {
            pass[i] = getChar(lower, upper, numeric);
        }


        FILE *fp = fopen("C:/PassGen/password.txt", "w");
        for(i = 0; i < passLength; i++) {
            putc(pass[i], fp);
        }
        fclose(fp);

        printf("\n\nSuccessful! The password is in a text file\nin C:/PassGen/\n");

        return 0;
    }
}

char getChar(int lower, int upper, int numeric) {
    int rand1;
    int fail;
    char passChar;

    do {
        fail = 0;
        rand1 = rand() % 3;

        switch(rand1) {
            case 0:
                if(lower) {
                    passChar = rand() % 26 + 97;
                } else {
                    fail = 1;
                }
                break;
            case 1:
                if(upper) {
                    passChar = rand() % 26 + 65;
                } else {
                    fail = 1;
                }
                break;
            case 2:
                if(numeric) {
                    passChar = rand() % 10 + 48;
                } else {
                    fail = 1;
                }
                break;
        }
    } while(fail);

    return passChar;
}

2 个答案:

答案 0 :(得分:1)

char pass[passLength];如果您的passLength数字很大,则此语句会产生问题。声明巨大的数组绝不是一个好习惯。

不要声明巨大的数组以避免缓冲区溢出。使用malloc代替分配大量内存。

您可以参考此How many chars can be in a char array?

答案 1 :(得分:0)

感谢@MOehm,我能够修改代码以删除此限制。新限制现在是(2 ^ 32)/ 2 - 1,或2,147,483,647。这更有意义,也比以前大得多。

理论上,通过使用比变量var add = function add() { var args = [].slice.call(arguments, 0); return args.reduce(function(sum, num) { return sum + num; }, 0); }; int更大的变量类型,我可以进一步扩展这个限制,但我没有任何真正的理由(而且我也许会风)如果我这样做了passLength文件占用我的整个硬盘驱动器。

修改后的代码:

.txt

我基本上删除了完全存储字符的数组,而是选择直接将字符写入FILE *fp = fopen("C:/PassGen/password.txt", "w"); int i; for(i = 0; i < passLength; i++) { putc(getChar(lower, upper, numeric), fp); } fclose(fp); 文件