2013-10-06 99 views
0

我想重新分配一个结构数组,当它将空间用完时,我将元素放入它中,但我一直收到一个realloc stderr。结构数组最终会有235,000个元素。当我将初始启动大小设置为100,000时,在尝试重新分配时收到stderr。如果我将初始开始大小设置为300,000,它不会给出错误,因为它从来没有达到realloc语句。结构数组内存realloc stderr

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

的realloc的错误发生在这里:

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; 

回答

1

因此,您最初将size设置为START_SIZE,即100,000。然后当你使用它时,你尝试分配sizeof(word) * size * GROW字节。 sizeof(word)大概是16个字节;我们知道size是100000,而GROW是1000.因此,可以为100,000,000个条目提供足够的空间,其中您将使用235,000个条目。这似乎是分配有点慷慨的一面。

100,000,000项的总空间为1,600,000,000字节。这看起来很多,但现在很多台式机都可以处理这个问题。但它似乎也没有令人惊讶的是realloc失败。

也许你应该让GROW东西比较合理,喜欢2.

顺便说一句,一旦你已经确定word_storage是NULL,则呼吁free(word_storage)没有意义的。这并没有什么坏处,因为free(NULL)是没有任何操作的,但同样的原因也没有好处。

0

您乘以1000的尺寸实在是太多了(高指数增长1 - > 1000 - > 1000 000 - > 1000 000 000 .. ),并且您不显示errno。我建议,而不是

size_t newsize = 3*size/2 + 1000; 
word_storage = realloc(word_storage, sizeof(word)*newsize); 
if (!word_storage) { 
    fprintf(stderr, "Cannot grow storage to %ld size, %s\n", 
        (long) newsize, strerror(errno)); 
    exit (EXIT_FAILURE); 
} 
else size = newsize; 

那么如果开始的1000的初始大小,你所得到的更合理的发展1000 - > 2500 - > 4750 - > 8125 - > 13187 - > 20780 ...更重要的是你最多花费50%的无用内存,而不是近1000倍!