2013-04-30 3 views
0

У меня есть отладка моей программы, и я не могу найти ответы. Моя программа принимает файл, копирует слова в динамический массив и хранит количество слов для краткости.Проблема с динамической программой ввода в C

Проблема 1) Для того, что я скомпилировал, я попытался использовать разные примеры ввода. Один читает «foo bar bat bam», а другой «foo foo bar bam». Первый выход все четыре слова в таком порядке, вторая печать

foo 
    bar  
    bam 
    foo bar bam 

Я не могу понять, почему это происходит.

Проблема 2) Я получаю ошибку сегментации при попытке инициализации вновь введенного слова для подсчета 1. Линия

arrayOfWords[unique_words].count = 1; 

дает мне ошибку сегментации. И использование -> не компилируется.

Проблема 3) Я не могу динамически вырастить массив. Я прокомментировал их сейчас, но вы можете увидеть мои две стратегии при попытке увеличить массив.

Я СЕРЬЕЗНО ОЦЕНИВАЮ ВАШУ ПОМОЩЬ!

#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define INITIAL_SIZE 10 

typedef unsigned int uint; 
typedef struct { char * word; int count; } wordType; 

int main(void) 
{ 
    wordType *arrayOfWords = (wordType*)malloc(1 * sizeof (wordType)); 
    wordType *tempArray; 
    FILE * inputFile; 
    char temp[50]; 
    uint i; 
    uint j; 
    uint unique_words; 
    uint exists; 
    uint wordAdded; 
    inputFile = fopen("input.txt", "r"); 



    if(inputFile == NULL) 
    { 
      printf("Error: File could not be opened\n"); 
      /*report failure*/ 
      return 1; 
    } 
    i = 0; 
    unique_words = 0; 
    wordAdded = 0; 
    while(fscanf(inputFile, "%s", temp) != EOF) 
    { 


     /*if a word was added, then increase the size by one 
     if(wordAdded == 1) 
    { 
     tempArray = malloc((unique_words + 1) * sizeof(wordType)); 
     memcpy(arrayOfWords, tempArray, unique_words + 1); 
     free(tempArray); 
     wordAdded = 0; 
    } */ 

    /* 
    if(wordAdded == 1) 
    { 
     arrayOfWords = realloc(arrayOfWords, unique_words + 1); 
     wordAdded = 0; 
    }*/ 

    exists = 0; 
    for(j = 0; j < unique_words; j++) 
    { 
     if(strcmp(arrayOfWords[j].word, temp) == 0) 
     { 
      arrayOfWords[j].count++; 
      exists = 1; 
     } 
    } 
    if(exists == 0) 
    { 
     arrayOfWords[unique_words].word = malloc(sizeof(char) 
           * (strlen(temp)+1)); 
     strcpy(arrayOfWords[unique_words].word, temp); 
     /*arrayOfWords[unique_words].count = 1; */ 
     unique_words++; 
     wordAdded = 1; 
    } 
    i++; 
} 
    printf("unique_words = %d\n", unique_words); 
    for(i = 0; i < unique_words; i++) 
    printf("%s\n", arrayOfWords[i].word); 


    fclose(inputFile); 
    /* for(i = 0; i < size; i++) 
     free(arrayOfWords[0].word);*/ 
    return 0; 
} 

ответ

1
int main(void){ 
    wordType *arrayOfWords = NULL; 
    FILE * inputFile = stdin; //stdin for simplification 
    char temp[50]; 
    uint i,j; 
    uint unique_words; 
    uint exists; 

    unique_words = 0; 
    while(fscanf(inputFile, "%s", temp) != EOF){ 
     exists = 0; 
     for(j = 0; j < unique_words; j++){ 
      if(strcmp(arrayOfWords[j].word, temp) == 0){ 
       arrayOfWords[j].count++; 
       exists = 1; 
       break; 
      } 
     } 
     if(exists == 0){//new word 
      arrayOfWords = realloc(arrayOfWords, (unique_words+1)*sizeof(wordType)); 
      arrayOfWords[unique_words].count = 1; 
      arrayOfWords[unique_words].word = malloc(sizeof(char)*(strlen(temp)+1)); 
      strcpy(arrayOfWords[unique_words].word, temp); 
      ++unique_words; 
     } 
    } 
    printf("unique_words = %d\n", unique_words); 
    for(i = 0; i < unique_words; i++) 
     printf("%s\n", arrayOfWords[i].word); 

    /* deallcate 
    for(i = 0; i < unique_words; ++i) 
     free(arrayOfWords[i].word); 
    free(arraOfWords); 
    */ 
    return 0; 
} 
+0

Спасибо за помощь, это многое проясняет. Выделение по мере необходимости, а не инициализация имеет смысл. – Busch

+0

Это было хорошо и полезно в вашем понимании. – BLUEPIXY

1

Вы закомментированы перераспределение, потому что это не сработало, и теперь он выходит из строя, потому что вы делать не перераспределить.

Как и в случае malloc, функция realloc нуждается в размере в байтах. Поэтому вы должны использовать, например,

arrayOfWords = realloc(arrayOfWords, sizeof(wordType) * (unique_words + 1)); 

Когда вы будете работать с этим перераспределением, ваша программа больше не будет разбиваться.


И в случае, если вам интересно, крах потому, что вы увеличиваете unique_words, но не перераспределять буфер. Это приведет к доступу к памяти за пределами выделенной вами памяти, которая является неопределенным поведением и может привести к сбоям (или другому странному поведению).

Смежные вопросы