简体   繁体   English

使用更多内存时C中的程序崩溃

[英]program in C is crashing when more memory is used

I have to do as a school assigment small program in C that will read standart input and prints some standart output. 我必须使用C做为学校布置的小程序,它将读取标准输入并打印一些标准输出。 To be more specific, it's about reading numbers and sorting them. 更具体地说,它与读取数字并对其进行排序有关。

(you can skip this, it's just for understanding the code) First line of the input should determine how many lines of numbers there will be. (您可以跳过此步骤,仅是为了了解代码)输入的第一行应确定将有多少行数字。 Second line is ammount of numbers in next line. 第二行是下一行中的数字量。 Third line are to concrete numbers. 第三行是具体数字。 Fourth line is ammount of numbers in next line and so on until it reaches K number of lines. 第四行是下一行的数字量,依此类推,直到达到K行数。 Restrictions are 0 < K <= 10 (max 10 sequences), each sequence can contain max 10.000.000 numbers and each number's value is max 10.000.000 限制为0 <K <= 10(最多10个序列),每个序列最多可包含10.000.000个数字,每个数字的值最大为10.000.000

Example Input: 输入示例

  1. 2 //which means that there will be 2 sequences (lines) of numbers and their corresponding ammount 2 //这意味着将有2个数字序列(线)及其对应的数量
  2. 3 //in the first sequence there will be 3 numbers 3 //在第一个序列中将有3个数字
  3. 5 99912 45 //first sequence 5 99912 45 //第一个序列
  4. 6 //in the second sequence there will be 6 numbers 6 //在第二个序列中将有6个数字
  5. 9489498 22131 0 521313 7988956 5 //second sequence 9489498 22131 0 521313 7988956 5 //第二个序列

Ouptup: Ouptup:

0 5 5 45 22131 99912 521313 7988956 9489498 0 5 5 45 22131 99912 521313 7988956 9489498

So I have done a working program but it seems to be unstable with higher values. 因此,我完成了一个工作程序,但似乎值较高,因此不稳定。 However I can't determine when and where exactly the program fails. 但是我无法确定程序何时何地失败。 On my computer, I have tested all possible max values and it returned correct output in reasonable time, but on a school server where tests are done it just can't handle high values and fails. 在我的计算机上,我已经测试了所有可能的最大值,并且在合理的时间内返回了正确的输出,但是在完成测试的学校服务器上,它无法处理高值并且失败了。

There is one thing, that the program should only use C, not C++, but I am not very sure of differences between them and as I was using C++ compiler, it's possible that my code isn't just raw C. 有一件事是,程序仅应使用C而不是C ++,但是我不确定它们之间的区别,而且由于我使用的是C ++编译器,因此我的代码可能不只是原始C。

I am a C beginner and this is something like "Hello world" for me, so please, can you just quick look through the code and say what can cause the unstability? 我是C语言的初学者,对我来说这就像是“ Hello world”,所以请您快速浏览一下代码并说出导致不稳定的原因吗? Thanks 谢谢

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

int main(void) {    
    int k, n, i, y, x, index = 0;
    int *numbers = (int*) malloc(100000000 * sizeof(int));
    if(numbers == NULL){
        exit(1);
    }
    scanf("%d", &k);
    for (x = 0; x < k; x++) {
        y = 0;
        scanf("%d", &n);
        while(scanf("%d", &i) > 0){
            numbers[index++] = i;
            if(++y == n){
                break;
            }
        }
    }
    for(y = 0;y < index;y++){   //find and print all 0's, because later I will use 0 as a
                                //already used (printed) element in array and ignore it      
        if(numbers[y] == 0){
            if(y == index-1){
                printf("0");
            }else{
                printf("0 ");
            }
        }
    }
    int smallest, smallestIndex;
    for(x = 0;x < index;x++){   //print all other numbers in ascending order
        smallest = 0;
        for(y = 0;y < index;y++){  //find current smallest number
            if((numbers[y] < smallest || smallest == 0) && numbers[y] != 0){
                smallest = numbers[y];
                smallestIndex = y;
            }
        }
        numbers[smallestIndex] = 0;
        if(smallest > 0){
            if(x == index-1){
                printf("%d", smallest);
            }else{
                printf("%d ", smallest);
            }
        }
    }
    free(numbers);
    numbers = NULL;
    return 0;
}

Based on the information you give, I think this is simply a resource limitation on the server. 根据您提供的信息,我认为这仅仅是服务器上的资源限制。 The server simply runs out of memory and your malloc() fails. 服务器只是内存不足而您的malloc()失败。 I suggest you debug or do this: 我建议您调试或执行以下操作:

if(numbers == NULL){
    printf("malloc() failed\n");
    exit(1);
}

The code for printing the initial zeros is suspicious: 用于打印初始零的代码是可疑的:

for(y = 0;y < index;y++){   //find and print all 0's, because later I will use 0 as a
                            //already used (printed) element in array and ignore it      
    if(numbers[y] == 0){
        if(y == index-1){
            printf("0");
        }else{
            printf("0 ");
        }
    }

Suppose you have a sequence with 0 as the last element (eg 1 2 3 4 5 0); 假设您有一个序列,最后一个元素为0(例如1 2 3 4 5 0); i guess this code will print just 0 with no space after it, and the subsequent code will print 1 2 3 4 5 , so you will get something like 01 2 3 4 5 . 我猜这段代码将只打印0 ,后面没有空格,随后的代码将打印1 2 3 4 5 ,所以您将得到类似于01 2 3 4 5

I understand that you want the output to be as beautiful as possible, that is, without a space at the end. 我了解您希望输出尽可能美丽,也就是说,末尾没有空格。 Please also note that a newline ( \\n ) at the end of output might be good. 另请注意,输出末尾的换行符( \\n )可能很好。

I rewrote beginning parts of your program to get you on the right path. 我重写了程序的开始部分,以使您走上正确的道路。 This should help you but I can't be sure since I don't really know what is causing your program to crash. 这应该可以为您提供帮助,但是我不确定,因为我真的不知道是什么导致您的程序崩溃。

This implements the realloc function which should make your program drastically more efficient than it is now. 这实现了realloc函数,该函数应使您的程序比现在的效率大大提高。 If you don't know what realloc is you can read about it here , and here . 如果您不知道什么是重新realloc ,可以在这里这里阅读

#include <stdio.h>
#include <stdlib.h>
#define BUFFER 256                                                  //for memory management         

int main(void) 
{    
    int k, n, i, y , x, index = 0, bff;                             //declare integer 'bff' and set it to BUFFER
    int *numbers = NULL, *tmp;                                      //declare a pointer (numbers) for allocated memory, and a pointer (tmp) for the realloc function

    if(!(numbers = malloc(BUFFER * sizeof(int))))                   //allocate space for 'bff' integers
    {
        exit(1);                                                    //allocation failed
    }
    scanf("%d", &k);
    for (x = 0; x < k; x++) 
    {
        scanf("%d", &n);
        while(scanf("%d", &i) > 0)
        {
            if(bff <= index)                                        //if the size of index grows larger than the amount of space we allocated
            {
                bff += BUFFER;                                      //increase the size of bff by BUFFER
                if(!(tmp = realloc(numbers, bff * sizeof(int))))    //resize our allocated memory block using the tmp pointer 
                {
                    free(numbers);                                      //allocation failed so free already allocated memory
                    exit(1);                                        //and terminate the program
                }
                numbers = tmp;                                      //make numbers point to the same location as tmp
                numbers[index++] = i;                               
                if(++y == n) break;
            }
        }
    }
    .
    .
    .
    free(numbers);
    return 0;
}

Keep in mind there are more efficient ways to use realloc. 请记住,有更有效的方法来使用realloc。 I just posted this here to get you on the right track. 我刚刚在这里发布了此信息,以使您走上正确的路。 Good luck! 祝好运!

You are allocating the wrong amount of memory. 您分配了错误的内存量。 The specification states that each sequence can contain 10 million values whereas you allocate a fixed amount. 规范指出, 每个序列可以包含1000万个值,而您分配的数量是固定的。 There may be up to k*10 million values of input, and you cannot know that the amount you allocate is enough. 可能有多达k * 1000万个输入值,并且您不知道分配的数量是否足够。

As pointed out by m0skit0, the problem may also be due to over-allocation. 如m0skit0所指出的,该问题也可能是由于过度分配。

To fix the problem you should allocate the needed amount of memory, no more, no less. 要解决该问题,您应该分配所需的内存量,不要多也不要少。 Use the sequence length provided for each sequence to do that. 使用为每个序列提供的序列长度来做到这一点。 Also, you need to check the return value of malloc and realloc . 另外,您需要检查mallocrealloc的返回值。 If the return value is NULL then the allocation failed and you should print an error message and exit . 如果返回值为NULL则分配失败,您应该打印一条错误消息并exit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM