2016-04-15 4 views
0

Со ссылкой на следующий код: После вызова функции CheckSMS и передачи структуры * DB1 поля обновляются в соответствии с вызовом strtok. Эта функция считывает и анализирует текстовое сообщение, сохраняя его содержимое в полях char * структуры БД.Сброс функций вызова передал глобальные поля структур

В основном цикле я позвонил Serial.println(DB1.last_order) до и после вызова функции CheckSMS. Если я получил текст, заказ печатается соответствующим образом в основном цикле, однако при следующем вызове CheckSMS очищается DB1.last_order, заменяется на \ n или NULL или что-то в этом роде. Я не могу понять, почему DB1.last_order не сохраняет свое значение и, скорее, перезаписывается при каждом вызове CheckSMS. Спасибо за любую помощь.

Примечание. Все текстовые сообщения содержат «CMT +», поэтому запись в DB1 происходит только при получении текста. Вызов CheckSMS, когда текст не получен, нужно просто пропустить.

int CheckSMS(Robot *DB1) { 

    int j = 0; 
    char response[100]; 
    char *pch; 
    unsigned long previous; 

    memset(response, '\0', 100); 

    while(Serial2.available()>0){ 
     response[j] = Serial2.read(); 
     j++; 
     Serial.println("inc"); 
    } 

    delay(100); 
    if (strstr(response, "CMT:") != NULL){ 
     DB1->new_message = strtok(response, " ,"); 
     DB1->last_phone = strtok(NULL, " ,"); 
     pch = strtok(NULL, " ,"); 
     DB1->last_date = strtok(NULL, " ,"); 
     DB1->last_time = strtok(NULL, " ,\n"); 
     DB1->last_order = strtok(NULL," ,\n"); 
     new_message = 1; 

    } 

    else{ 
    } 

    return 0; 
} 
+0

Предполагая, что вы действительно прочитали данные, как только эта функция вернет все указатели 'char *', которые вы вырвали из этих вызовов 'strtok' и сохранили в' DB1', будет свисать (например, уже недействительно), поскольку буфер, к которому они ссылаются (указывать), 'response []', больше не существует. [** Этот пост **] (https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794) * серьезно * стоит читать. – WhozCraig

ответ

2

strtok функция возвращает указатель на строку, вы tokenizing, местный массив response в вашем случае. Когда функция возвращает массив response, он выходит из области видимости и исчезает, оставляя вашу структуру указателями на строку, которая больше не существует, и дает вам неопределенное поведение.

У вас есть несколько решений:

  • Выделяют строку динамически с помощью malloc, но тогда вы должны сохранить его в структуре, так что вы можете free его, когда вы сделали со структурой
  • Make массив responsestatic, но затем следующий вызов функции будет иметь тот же массив, ведущий к обновлению старых данных.
  • Передайте строку, чтобы сохранить ответ и использовать эту строку, строка должна иметь срок службы как минимум как поскольку структура и не меняйте содержимое. Строка, конечно, может быть членом самой структуры
+0

Было бы разумным, чтобы мои 'struct' имели массивы char, а не указатели? И скопируйте их в ответ? –

0

Ответ Joachim дал правильно, я просто хочу добавить, что вы могли бы также изменить структуру робота, чтобы содержать массивы символов (например: char new_message[MAX_BUF_CHARS]; и так далее). Убедитесь, что в них достаточно места. Затем вместо назначения указателей, возвращаемых из strtok, скопируйте строки там.

+0

ой .. да .. это был мой вопрос в комментарии к Иоакиму. благодаря –