массив удаляет сам первые 3 символа в C

#arrays #c #string

Вопрос:

У меня есть эта структура данных:

 struct WordCounter
{
  char *word;
  int word_count;
  struct WordCounter *pNext;                        /* Pointer to the next word counter in the list */
};
 

Мне это нужно, чтобы запомнить слова, прочитанные из файла, и сколько раз они встречаются. Эта структура имеет следующие функции:

 int giveCounter (struct WordCounter *pCounter){   // give the occurrence of the current word in the linked list
    int tempcount = pCounter -> word_count;
   return tempcount;
    
}

int lengthOfCurrentWord(struct WordCounter *pWordCounter) // length of the current string
{
    
    return strlen(pWordCounter->word) 1;  // for the null terminator string 
}

char* giveWord(struct WordCounter *pWordcounter){  // return current word of the linked list
    return pWordcounter->word;
}
 

Что я должен сделать, так это взять все слова в списке и поместить их в массив, который может содержать их все, где каждое слово разделено терминатором.
Код такой, и после того, как я объясню, в чем проблема:

 pCounter = pStart; // go to the first element in the linked list
num_car=0;  // in total how much character in all words
while(pCounter != NULL){
    num_car  = lengthOfCurrentWord(pCounter);
    pCounter = pCounter -> pNext;
}
printf("total number of chars in all words is: %d n ", num_car);
 

Хорошо, теперь у нас есть размер большого массива, в котором нужно сохранить все слова, разделенные терминатором.

 char *exactly_word; // im forced to initialize like this and after i can  give the exactly number of elements
exactly_word = malloc(sizeof(char)*num_car); // The big array
memset(exactly_word,0,num_car);
 

Давайте начнем копировать слово из связанного списка в большой массив:

 char wordy[100] = {0}; // an array for the temp word
pCounter = pStart;  // go to the first element
int indice = 0;   // used for loop through single word
int indice_parole = 0;  // It is used to indicate in which position of the large array to insert the character
for(int x=0; x<readed_nd_word;x  ){   // readed_nd_words is the number of element in the linked list
    
    strcat(wordy,giveWord(pCounter));  // copy the current word into wordy array
    printf("WORDY: %s n",wordy);      // yeah correct in each iteration
   
    while(wordy[indice]!= 0){
        printf("Character to add to exactly word: %c, at position: %d n",wordy[indice],indice_parole);
        exactly_word[indice_parole] = wordy[indice]; // copy character
        indice_parole  ;
        indice  ;
    }
    

    pCounter = pCounter -> pNext; // move into next word in the linked list
    memset(wordy,0,100);   // reset for a new word
    indice = 0;
    
    exactly_word[indice_parole] =0; // terminator for separating words
    printf("Terminator at position %d",indice_parole);
    indice_parole  ; 
    
    
}
 

В чем проблема? хорошо, в цикле while точное слово заполняется правильно, но после этого кода, если я попытаюсь напечатать точное слово[0], на выходе будет:»», то же самое для позиции 1,2 точного слова. Я могу лучше объяснить проблему на примере, который я описываю с выводом:

 words in the linked list:
  wut   1
  sut   1
  ov   1
  word   2
  ciao   1
  helo   1
  cor   1
  fal   1
  vermalen   1

total number of chars in all words is: 43 (countered the terminator too)
WORDY: wut 
Character to add to exactly word: w, at position: 0
Character to add to exactly word: u, at position: 1
Character to add to exactly word: t, at position: 2
terminator at position 3

WORDY: sut 
Character to add to exactly word: s, at position: 4
Character to add to exactly word: u, at position: 5 
Character to add to exactly word: t, at position: 6 
terminator at position 7
 

Для остальных слов вывод правильный, но после этого кода, как я уже сказал, если я напечатаю точное слово[0], я получу»», такое же, как 1,2, вместо точного слова[4] = «s» от слова sut.
Если я распечатаю весь массив, у меня получится следующее: «sutovwordciaohelocorfalvermalen».

P. s. ошибка не появляется при каждом запуске, иногда она появляется, а иногда нет, когда она не появляется, слово исправлено. Есть что-то вроде непобедимого поведения, которого я не вижу? пожалуйста, помогите 🙁

Комментарии:

1. Как общее замечание (хотя и не является причиной ошибок), sizeof(char) всегда 1 по определению (размеры указаны в единицах символов), поэтому умножение не требуется. (Если вы хотите, чтобы тип был четким, ИМО, лучше использовать шаблон str = malloc(sizeof(*str) * len) )

2. @Arkku да, я вижу ошибку с позицией, но почему отсутствуют первые 3 символа? И почему поведение такое странное?

3. В СТОРОНУ: Вы могли бы измениться strcat(wordy,giveWord(pCounter)); на strcpy(wordy,giveWord(pCounter)); . Затем char wordy[100] = {0}; может быть изменен char wordy[100]; и memset(wordy,0,100); может быть удален.

4. @IanAbbott, это и есть ошибка?

5. Вместо того, чтобы печатать массив в виде текста, попробуйте напечатать каждый символ, например, в шестнадцатеричном формате, например, с printf(" x", exactly_word[index]) помощью . Возможно, какой-то управляющий персонаж возится с вашим терминалом.

Ответ №1:

В комментарии вы показываете нам шестнадцатеричный дамп exactly_word to be

  01 00 00 00 73 75 74 00 6f 76 00 77 6f 72 64 ...
 

это указывает на то, что у вас есть перезапись в памяти первых 3 (возможно, 4) байтов exactly_word . Похоже, что целочисленное значение 1 было записано в начало массива (малый конец), но это всего лишь предположение, потому что: этого не происходит в опубликованном коде. Это должно быть в коде, который вы нам не показывали.

Тем не менее, ваш текущий код слишком сложен. Упростите это, как:

 exactly_word = malloc(num_car);
char* dst = exactly_word;
pCounter = pStart;
while(pCounter){
    strcpy(dst, giveWord(pCounter));
    dst  = lengthOfCurrentWord(pCounter);  // which includes termination char
    pCounter = pCounter -> pNext;
}
 

Комментарии:

1. Для опубликованного кода я никогда не использую точное слово, поэтому его использование начинает формировать опубликованный код, после этого я просто печатаю точное слово, и именно здесь происходит волшебство, у меня много кода, исключающего это, но возможно ли, что предыдущий код повлияет на рассматриваемый код?

2. Я что-то пропустил, мое точное слово объявлено так: char *exactly_word; это проблема? Я вынужден инициализировать таким образом, потому что я программирую в mpi, и второй процессор (ведомый) не может знать, насколько точно размерен_слово при запуске. Поэтому я даю измерение в той части кода, когда у меня есть num_car, но для других вещей мне нужно, чтобы оно было объявлено до и заполнено после @4386427

3. @GabrielePisapia Я не могу отлаживать код, который ты мне не показываешь!!! Опубликованный код работает нормально. Видишь ideone.com/QmvugI Поэтому я могу только повторить: ваша ошибка в коде, который не опубликован

4. @GabrielePisapia Теперь вы упоминаете mpi . Я мало что знаю об этом, но AFAIK, это какая-то многопоточная среда, не так ли? В любом случае это может быть вероятным источником вашей ошибки: ваш опубликованный код работает нормально