簡體   English   中英

使用更多內存時C中的程序崩潰

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

我必須使用C做為學校布置的小程序,它將讀取標准輸入並打印一些標准輸出。 更具體地說,它與讀取數字並對其進行排序有關。

(您可以跳過此步驟,僅是為了了解代碼)輸入的第一行應確定將有多少行數字。 第二行是下一行中的數字量。 第三行是具體數字。 第四行是下一行的數字量,依此類推,直到達到K行數。 限制為0 <K <= 10(最多10個序列),每個序列最多可包含10.000.000個數字,每個數字的值最大為10.000.000

輸入示例

  1. 2 //這意味着將有2個數字序列(線)及其對應的數量
  2. 3 //在第一個序列中將有3個數字
  3. 5 99912 45 //第一個序列
  4. 6 //在第二個序列中將有6個數字
  5. 9489498 22131 0 521313 7988956 5 //第二個序列

Ouptup:

0 5 5 45 22131 99912 521313 7988956 9489498

因此,我完成了一個工作程序,但似乎值較高,因此不穩定。 但是我無法確定程序何時何地失敗。 在我的計算機上,我已經測試了所有可能的最大值,並且在合理的時間內返回了正確的輸出,但是在完成測試的學校服務器上,它無法處理高值並且失敗了。

有一件事是,程序僅應使用C而不是C ++,但是我不確定它們之間的區別,而且由於我使用的是C ++編譯器,因此我的代碼可能不只是原始C。

我是C語言的初學者,對我來說這就像是“ Hello world”,所以請您快速瀏覽一下代碼並說出導致不穩定的原因嗎? 謝謝

#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;
}

根據您提供的信息,我認為這僅僅是服務器上的資源限制。 服務器只是內存不足而您的malloc()失敗。 我建議您調試或執行以下操作:

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

用於打印初始零的代碼是可疑的:

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 ");
        }
    }

假設您有一個序列,最后一個元素為0(例如1 2 3 4 5 0); 我猜這段代碼將只打印0 ,后面沒有空格,隨后的代碼將打印1 2 3 4 5 ,所以您將得到類似於01 2 3 4 5

我了解您希望輸出盡可能美麗,也就是說,末尾沒有空格。 另請注意,輸出末尾的換行符( \\n )可能很好。

我重寫了程序的開始部分,以使您走上正確的道路。 這應該可以為您提供幫助,但是我不確定,因為我真的不知道是什么導致您的程序崩潰。

這實現了realloc函數,該函數應使您的程序比現在的效率大大提高。 如果您不知道什么是重新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;
}

請記住,有更有效的方法來使用realloc。 我剛剛在這里發布了此信息,以使您走上正確的路。 祝好運!

您分配了錯誤的內存量。 規范指出, 每個序列可以包含1000萬個值,而您分配的數量是固定的。 可能有多達k * 1000萬個輸入值,並且您不知道分配的數量是否足夠。

如m0skit0所指出的,該問題也可能是由於過度分配。

要解決該問題,您應該分配所需的內存量,不要多也不要少。 使用為每個序列提供的序列長度來做到這一點。 另外,您需要檢查mallocrealloc的返回值。 如果返回值為NULL則分配失敗,您應該打印一條錯誤消息並exit

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM