Article From:https://www.cnblogs.com/qsyll0916/p/9061841.html

Arrays and pointers are good things in C, but if they are not used properly, they will really drive people crazy.

Here is an array crossing experience encountered when writing a program. It feels a little enlightening for writing programs in the future, so it is recorded.

 

Cause:

I want to use OLED to display a set of floating point numbers dynamically, and the length of floating point numbers is variable.

1、If it is simply shown and there is no blanking, the residue of the last length will affect the display of the next short length data.

2、If a display area is emptied once, the data will always shake. At first I think it is not enough for me to refresh frequency, so the refresh frequency is changed from 100HZ to 1000HZ, but the effect is the same as before!

Later, I think that no matter how much I refresh the frequency, the blank and the displayed data are the same frequency. 1000Hz displays data, which is also the blank of 1000Hz. So it will shake badly.

3、Take every bit of data out and display it individually, but this brings the problem of data alignment. Not good, not good, abandon it.

4、Use sprintf to format data that needs to be displayed as strings. The display string is then displayed in the way of OLED’s display string.

 

So there’s the following procedure:

    sprintf((char *)weight_string,"%.1f",weight);        //Formatted as a string
    Clear_Left_Num(money_string);                                //Eliminate the remnants
    OLED_Show_String(42,2,weight_string);

    sprintf((char *)price_string,"%d",price);
    Clear_Left_Num(money_string);
    OLED_Show_String(42,4,price_string);

This program is called in the timer interrupt function. Weight and price are the floating-point numbers I want to show.

First, it is formatted as a string and then displayed. The first two parameters of OLED_Show_String () are the starting and displaying coordinates of characters.

Clear_Left_Num The function is as follows:

void Clear_Left_Num(unsigned char *num_string)
{
    while(*num_string != '.')
        num_string++;
    //The data behind a decimal point is refreshed with a space
    *(num_string+2) = ' ';
    *(num_string+3) = ' ';
    *(num_string+4) = ' ';
}

The idea is to refresh the residual data after the decimal point with space.

But the experiment is that after the first line of data is displayed, second data should have been displayed on the second line, but after the first line of data, he shows the second lines of data! That is to say, second lines of data are displayed two times.

Why do you show it two times? I wrote in the program, ah,,,

 

Analysis:

Since it is a problem, let’s look at this display function first.

/*----------------------------------
**Function name: OLED_Show_String* function description: the cursor displays the string, the string can be represented by an array, unsigned char string_2[] = {"THIS IS A TEST"};* * *Parameter Description: X, Y is the coordinate* Chr: string first address* * Author: Andrew* * * date: 2018.1.24- -- - --- - ----*/
void OLED_Show_String(u8 x, u8 y, u8 *chr)
{
    u8 j=0;
    while (chr[j]!='\0')
    {
        OLED_ShowChar(x,y,chr[j]);

        x+= 8 ;

        if(x>120){x=0;y+=2;}  //Automatic line writing

        j++;
    }
}

This function will display all the contents of the array before the end of the array. Because the last end of the array is a sign. ‘\0’

So, the first line above is always showing,Indicates that he may not have encountered an array end identifier.

Look at the size of the array definition:

unsigned char weight_string[7] = {0};
unsigned char price_string[3] = {0};

The last stop sign of the weight_string array was assigned to space. Then he will always read the memory data stored behind this array and display it. It is called the “array crossing the boundary”.

Luckily, we just read the display and did not rewrite the data.

Now that he shows the data of the second row, it shows that the data of the second row is stored in the memory behind this array.

Look at the map file generated by the compiler:

Sure enough, the second array is next to the first array store.

After the first array reads out of bounds, it reads second arrays.

Here, the problem is solved.

 

Summary:

Be sure to see the inner link of the program. Analyzing memory is difficult, but it is a shortcut to find annoying bug.

 

Leave a Reply

Your email address will not be published. Required fields are marked *