结构数组内存重新分配stderr [英] Array of Structs memory realloc stderr

查看:77
本文介绍了结构数组内存重新分配stderr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我将元素放入数组时,我正在尝试重新分配结构数组,但是我一直收到重新分配的stderr.结构数组最终将包含235,000个元素.当我将初始起始大小设置为100,000时,尝试重新分配时会收到stderr.如果我将初始起始大小设置为300,000,则不会给出错误,因为它永远不会到达realloc语句.

I am trying to realloc an array of structs when it runs out of space as I'm putting elements into it but I keep receiving a realloc stderr. The array of struct will eventually have 235,000 elements in it. When I set the initial start size to 100,000 I receive the stderr when trying to realloc. If I se the initial start size to 300,000 it does not give the error because it never reaches the realloc statement.

#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

#define BUFFERLEN 200
#define START_SIZE 100000
#define GROW 1000
#define TRUE 1
#define FALSE 0

typedef struct{
    char *forw;
    char *back;
} word;

typedef struct{
    char *entry;
} single_words;


FILE *words;
/*-------------Function Prototypes------------*/
void reverse(char* string, char* revstr, int len);
int search_struct(char* find, word* words, int length);
int compare(const void* eventa, const void* eventb);
int length(char* string);


int main(void)
{
    char *buffer;
    int letter_index[26];
    char alpha[] = "abcdefghijklmnopqrstuvwxyz";
    int i=0, found = FALSE, strlen=0, letter=0;
    word *word_storage;
    single_words *output_storage;
    int num_words = 0, size = 0;
    int num_output = 0, output_size = 0;

    /*buffer for the input strings of the words in the input file*/
    buffer = (char*) malloc (sizeof(char)*BUFFERLEN);
        if(!buffer){
            fprintf(stderr, "Error in buffer string mem alloc\n");
            exit(1);
        }   

    /*Initializing the array of structs to store the forward and reverse of each word*/
    word_storage = (word*) malloc (sizeof(word)*START_SIZE);
        if(!word_storage){
            fprintf(stderr, "Error in word_storage string mem alloc\n");
            exit(1);
        }
        size = START_SIZE;

    /*Initializing the array of structs for the output*/
    output_storage = (single_words*) malloc (sizeof(single_words)*START_SIZE);
        if(!output_storage){
            fprintf(stderr, "Error in output_storage mem alloc\n");
            exit(1);
        }
        output_size = START_SIZE;   

    /*Set the letter index 0(which is a) to the first character*/
    letter_index[0] = 0;

    words = fopen("words", "r");

    /*Read the words(forward and reverse) in from stdin into the word_storage*/
    while(fgets(buffer, BUFFERLEN, words) != NULL){
        buffer = strtok(buffer, "\n");
        strlen = length(buffer);
        if (num_words < size){
            /*Allocate memory for the forward and reverse strings*/
            word_storage[num_words].forw = (char *) malloc (sizeof(char) * strlen);
                if(!word_storage[num_words].forw){
                    free(word_storage[num_words].forw);
                    fprintf(stderr, "word_storage forward string malloc was unsuccessful");
                    exit(1);
                }
            word_storage[num_words].back = (char *) malloc (sizeof(char) * strlen);
                if(!word_storage[num_words].back){
                    free(word_storage[num_words].back);
                    fprintf(stderr, "word_storage forward string malloc was unsuccessful");
                    exit(1);;
                }               

            /*Store the forward and reverse in the strings*/
            strncpy(word_storage[num_words].forw, buffer, strlen);
            reverse(word_storage[num_words].forw, word_storage[num_words].back, strlen);
            printf("%d: %s %s\n", num_words, word_storage[num_words].forw, word_storage[num_words].back);

            /*Increment the letter if it changes*/
            if(word_storage[num_words].forw[0] != alpha[letter]){
                letter++;
                letter_index[letter] = num_words + 1;
            }
            num_words++;
        }
        else{
            /*Increase the size of word_storage*/
            word_storage = (word*) realloc (word_storage, sizeof(word) * size * GROW);
                if(!word_storage){
                    free(word_storage);
                    fprintf(stderr, "Error in word_storage realloc string mem realloc\n");
                    exit(1);
                }
            size = size * GROW;
        }       
    }


    return 0;
}

重新分配错误发生在这里:

The realloc error occurs here:

word_storage = (word*) realloc (word_storage, sizeof(word) * size * GROW);
    if(!word_storage){
      free(word_storage);
      fprintf(stderr, "Error in word_storage realloc string mem realloc\n");
      exit(1);
     }
     size = size * GROW;

推荐答案

因此,您最初将size设置为START_SIZE,即100,000.然后,当您用尽它时,您尝试分配sizeof(word) * size * GROW字节. sizeof(word)大概是16个字节;我们知道size是100000,而GROW是1000.这样就可以算出足够的空间来容纳100,000,000个条目,您说您将使用235,000.分配似乎有点慷慨.

So, you initially set size to START_SIZE, which is 100,000. Then when you use that up, you try to allocate sizeof(word) * size * GROW bytes. sizeof(word) is presumably 16 bytes; we know that size is 100000, and GROW is 1000. So that works out to enough space for 100,000,000 entries, of which you say you will use 235,000. That seems like the allocation is a bit on the generous side.

100,000,000个条目的总空间为1,600,000,000字节.这似乎很多,尽管如今许多台式机都可以处理.但是,realloc失败似乎也不足为奇.

The total space for 100,000,000 entries is 1,600,000,000 bytes. That seems like a lot, although these days many desktop machines could handle that. But it doesn't seem too surprising that realloc fails.

也许您应该使GROW更加合理,例如2.

Perhaps you should make GROW something more reasonable, like 2.

顺便说一句,一旦确定word_storage为NULL,就没有必要调用free(word_storage)了.因为free(NULL)是无操作的,所以它没有害处,但出于相同的原因也没有好处.

By the way, once you've established that word_storage is NULL, there is no point in calling free(word_storage). It does no harm, since free(NULL) is a no-op, but it also does no good for the same reason.

这篇关于结构数组内存重新分配stderr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆