2016-11-25 5 views
0

Hy У меня есть образец кода bleow, который должен написать «MSG» таким образом, чтобы ЖК-дисплей (бегущий текст), и когда он доходил до конца, он снова стирался, но когда я выделить память для «LCD» (который должен быть 10 символов + завершение 0) заполняет его связкой случайных символов. Sample pictureСтранные символы при распределении памяти для char *

#include "stdafx.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 



void delay(unsigned int mseconds) 
{ 
    clock_t goal = mseconds + clock(); 
    while (goal > clock()); 
} 

int main() 
{ 

    int LCDSize = 10; 
    int MSGSize; 
    char* LCD = (char *)malloc(LCDSize+1); 
    char* MSG = (char *)malloc(80); 
    MSG = "This is a long message, probabli will move."; 
    MSGSize = strlen(MSG); 
    if (MSGSize <= LCDSize) 
    { 
     printf(MSG); 
    } 
    else 
    { 
     char* tmpMSG; 
     int j = 0; 
     while (j < 2) 
     { 
      for (int i = 0; i < MSGSize - LCDSize + 1; i++) 
      { 
       tmpMSG = MSG+i; 
       strncpy(LCD, tmpMSG, LCDSize); 
       strcat(LCD,"\0"); 
       printf(LCD); 
       delay(200); 
       system("cls"); 

      } 
      printf("----------"); 
      j++; 
     } 
    } 

    getchar(); 
    return 0; 
} 

Что может быть проблема?

+0

Использование 'printf (MSG);' это не очень хорошая идея; вы должны использовать 'printf ("% s ", MSG);'. Здесь не так важно, потому что пользователь не может управлять содержимым сообщения, а сообщение не содержит процентных символов (если все работает правильно), но в целом с данными, предоставленными пользователем, для печати, то, что вы использовали, является потенциально смертельным. Они называются «уязвимостьми форматированной строки». –

ответ

3
  strncpy(LCD, tmpMSG, LCDSize); 
      strcat(LCD,"\0"); 

strncpy функция не будет прекращена, если она не подходит. В этом случае он не подходит. Так что прекращения нет. Что-то, что не завершено нулевым байтом, равно , а не - юридическая строка, поэтому вы не можете передать указатель на нее как первый параметр на strcat, но вы это сделаете.

Функция strcat добавляет одну строку в другую. Обе строки должны быть законными, хорошо сформированными строками или вы не должны звонить strcat.

Это одна из причин, как правило, предполагается, что вы не использование strncpy - нет никакой гарантии, результатом является действительной строкой, и это легко сделать такую ​​ошибку вы сделали. Да, вы убедились, что вы не переполнили буфер, когда вы вызывали strncpy, ограничивая размер, но вы не гарантировали, что буфер содержит допустимую строку.

Возможно, вы хотели, чтобы LCD[LCDSize]='\0'; вместо звонка на strcat. Это гарантирует, что буфер прекращен.

+0

Технически говоря, любой буфер в конечном итоге заканчивается нулевым байтом, поэтому любой буфер на самом деле является юридической строкой :) – m0skit0

+1

@ m0skit0: Нет. Если в пространстве, выделенном для буфера, нет нулевого байта, буфер не является юридическая строка. Там будет, в конечном счете, нулевой байт где-то вне диапазона буфера, который, вероятно, будет рассматриваться как завершение для строки, но вы до сих пор не выполняете «неопределенное поведение» - все может произойти. –