пропущенные записи в массиве строковых значений - PullRequest
0 голосов
/ 16 мая 2019

Я пытаюсь создать массив строк const char, используемый для идентификации некоторых аппаратных каналов.Затем я хочу получить эти записи по индексу, чтобы пометить выходные данные на пользовательской консоли.Некоторые из этих каналов не назначены и помечены как таковые строкой «XX_UNASSIGNED_XX», поэтому это значение повторяется в массиве.

Когда я пытаюсь последовательно отобразить эти значения в моем тестовом коде, я вижу, что XX_UNASSIGNED_XX появляется только один раз и впоследствии пропускается.Я открыл трассировку памяти во встроенном оборудовании, и, конечно же, в памяти только XX_UNASSIGNED_XX перечисляется только один раз, я полагаю, что-то вроде оптимизации.

Есть ли способ заставить компилятор перечислять все записи в памяти как есть, дубликаты и все?Или, возможно, мне не нужно этого делать, и способ, которым я пытаюсь отобразить строки, неверен или неэффективен и может быть улучшен?

Я поэкспериментировал с тем, как отображать строки, и поскольку в конечном итоге это массив указателей с каждой строкой разной длины, в конечном итоге я записал длину каждой строки, отслеживая массив с помощью переменной указателязатем с помощью snprintf скопируйте строку во временную строку, которую я затем отобразлю.Любая попытка напрямую напечатать значения в массиве приводила к аномальному поведению, которое я не мог исправить.

FYI Команда Display_printf - это просто printf для терминала UART с синтаксисом следующим образом:

Display_printf(UART_handle,col_index, row_index, display_text))
    #define ADC_COUNT (20)

    const char* adcNamesArray[ADC_COUNT] = {
        "KP_CUR_MON",
        "A_CUR_MON",
        "A_VOLT_MON",
        "NEG_15_VOLT_MON",
        "XX_UNASSIGNED_XX",
        "FOCUS_CUR_MON",
        "XX_UNASSIGNED_XX",
        "XX_UNASSIGNED_XX",
        "K_CUR_MON",
        "XX_UNASSIGNED_XX",
        "XX_UNASSIGNED_XX",
        "XX_UNASSIGNED_XX",
        "FOCUS_VOLT_MON",
        "FARADAY_MON",
        "MFC_MON",
        "XX_UNASSIGNED_XX",
        "POS_12_VOLT_MON",
        "POS_24_VOLT_MON",
        "POS_15_VOLT_MON",
        "POS_5_VOLT_MON"
    };

    char str[20];
    char* ptr = &adcNamesArray[0];
    char* printPtr;
    int nameLength;

    for(int adc_index = 0; adc_index < ADC_COUNT; adc_index++) {
        nameLength = 0;

        while(*ptr == '\0') {
            ptr += sizeof(char);
        }
        printPtr = ptr;

        while(*ptr != '\0') {
            ptr += sizeof(char);
            nameLength++;
        }
        nameLength++;

        char* str;
        str = (char *)malloc((sizeof(char)*nameLength+1));
        snprintf(str, nameLength, "%s", printPtr);

        Display_printf(display,0,0,"ADC %d: %s", adc_index, str);
    }

Итак, я ожидаю, что все записи XX_UNASSIGNED_XXпоказывать по порядку, но вместо этого я получаю следующее:

ADC 0: KP_CUR_MON  
ADC 1: A_CUR_MON  
ADC 2: A_VOLT_MON  
ADC 3: NEG_15_VOLT_MON   
ADC 4: XX_UNASSIGNED_XX   
ADC 5: FOCUS_CUR_MON   
ADC 6: K_CUR_MON   
ADC 7: FOCUS_VOLT_MON   
ADC 8: FARADAY_MON   
ADC 9: MFC_MON   
ADC 10: POS_12_VOLT_MON   
ADC 11: POS_24_VOLT_MON   
ADC 12: POS_15_VOLT_MON   
ADC 13: POS_5_VOLT_MON   
ADC 14: ▒   
ADC 15: @   
ADC 16: ▒▒▒▒   
ADC 17: @▒   
ADC 18:   
ADC 19:  

Это дает дамп памяти, который объясняет, почему XX_UNASSIGNED_XX не появляется несколько раз.

0x0001C0D8  .  .  .  .  .  .  .  0  K  P  _  C  U  R  _  M  
0x0001C0E8  O  N  .  .  A  _  C  U  R  _  M  O  N  .  .  .  
0x0001C0F8  A  _  V  O  L  T  _  M  O  N  .  .  N  E  G  _  
0x0001C108  1  5  _  V  O  L  T  _  M  O  N  .  X  X  _  U  
0x0001C118  N  A  S  S  I  G  N  E  D  _  X  X  .  .  .  .  
0x0001C128  F  O  C  U  S  _  C  U  R  _  M  O  N  .  .  .  
0x0001C138  K  _  C  U  R  _  M  O  N  .  .  .  F  O  C  U  
0x0001C148  S  _  V  O  L  T  _  M  O  N  .  .  F  A  R  A  
0x0001C158  D  A  Y  _  M  O  N  .  M  F  C  _  M  O  N  .  
0x0001C168  P  O  S  _  1  2  _  V  O  L  T  _  M  O  N  .  
0x0001C178  P  O  S  _  2  4  _  V  O  L  T  _  M  O  N  .  
0x0001C188  P  O  S  _  1  5  _  V  O  L  T  _  M  O  N  .  
0x0001C198  P  O  S  _  5  _  V  O  L  T  _  M  O  N  .  .  
0x0001C1A8  uartMSP432E4HWAttrs  
0x0001C1A8  .  .  .  @  .  .  .  .  .  .  .  .  .  .  .  .  
0x0001C1B8  @  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 16 мая 2019

Вы предполагаете, что тексты находятся в памяти в одном месте или разделены одним или несколькими символами NUL.Это предположение неверно.

Это объявляет массив указателей на ваши тексты:

const char* adcNamesArray[ADC_COUNT] = {
...

Просто используйте этот массив, и ваш код внезапно станет намного проще и правильнее.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ADC_COUNT (20)

int main(void)
{
  const char* adcNamesArray[ADC_COUNT] = {
         "KP_CUR_MON",
         "A_CUR_MON",
         "A_VOLT_MON",
         "NEG_15_VOLT_MON",
         "XX_UNASSIGNED_XX",
         "FOCUS_CUR_MON",
         "XX_UNASSIGNED_XX",
         "XX_UNASSIGNED_XX",
         "K_CUR_MON",
         "XX_UNASSIGNED_XX",
         "XX_UNASSIGNED_XX",
         "XX_UNASSIGNED_XX",
         "FOCUS_VOLT_MON",
         "FARADAY_MON",
         "MFC_MON",
         "XX_UNASSIGNED_XX",
         "POS_12_VOLT_MON",
         "POS_24_VOLT_MON",
         "POS_15_VOLT_MON",
         "POS_5_VOLT_MON"
  };

  for (int adc_index = 0; adc_index < ADC_COUNT; adc_index++)
  {
    char *str = malloc(strlen(adcNamesArray[adc_index]) + 1);
    strcpy(str, adcNamesArray[adc_index]);
    printf("ADC %d: %s\n", adc_index, str);
  }
}

Если по какой-либо причине на вашей платформе нет strcpy или strlen, вы можете реализовать их самостоятельно, они являются однострочными.

Некоторые пояснения:

  • sizeof char равен 1 по определению, так что вы можете отбросить его
  • приведение (char*) не обязательно с malloc, ставить один не неправильно, но вы получаете нулевое преимуществопри этом.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...