C 为什么值会被覆盖?

C 为什么值会被覆盖?,c,atmel,freertos,cortex-m,C,Atmel,Freertos,Cortex M,首先,对不起,我知道这很长,人们可能不会全部阅读,但我认为它需要一个非常详细的解释 我正在尝试使用FreeRTOS在Cortex M4上处理Chan Fat文件的长文件名。我遇到了一件奇怪的事情,出于某种原因,指针被一段看似未连接的代码覆盖。你会期望堆栈溢出哈!,但是我的堆栈是巨大的,我试着从我第一次遇到这个问题的时候开始进一步增加它,我真的不认为会是这样 我有以下代码: uint16_t w, *lfn; lfn = dj->lfn; *tp = fno->lfname;

首先,对不起,我知道这很长,人们可能不会全部阅读,但我认为它需要一个非常详细的解释

我正在尝试使用FreeRTOS在Cortex M4上处理Chan Fat文件的长文件名。我遇到了一件奇怪的事情,出于某种原因,指针被一段看似未连接的代码覆盖。你会期望堆栈溢出哈!,但是我的堆栈是巨大的,我试着从我第一次遇到这个问题的时候开始进一步增加它,我真的不认为会是这样

我有以下代码:

uint16_t w, *lfn;
lfn = dj->lfn;     
*tp = fno->lfname;
while ((w = *lfn++) != 0) 
{           /* Get an LFN char */
    if (i >= fno->lfsize - 1) 
    { 
       i = 0; 
       break; 
    }   /* Buffer overflow, no LFN */
    tp[i] = (TCHAR)w;
    i++;
}
lfn是指向16位值的指针。w是一个16位的值

线tp[i]=TCHARw;在汇编程序中有以下内容:

6A7B        ldr r3, [r7, #0x24]
005B        lsls r3, r3, #1
68FA        ldr r2, [r7, #12]
4413        add r3, r2
897A        ldrh r2, [r7, #10]
801A        strh r2, [r3]
在循环的最初几次中,一切都很好。lfn从0x20009c68开始以2的跳跃方式递增,正如您所期望的那样。然而,当lfn到达0x20009c72并且代码到达行tp[i]=TCHARw时;事情变得一团糟

汇编器的前两行取i的值,将其左移1以获得正确的偏移量

接下来的两行将tp的地址放入r2,然后添加r3的内容,这也是必需的偏移量

ldrh r2, [r7, #10] then puts w in r2 
最后,

strh r2, [r3]
将w存储到r3指向的位置,这是tp指向的必要位置

当lfn到达0x20009c72时,汇编器的最后一行将0x2000061放入lfn。这是导致真正问题的原因。在此之前,它正确地将r2(即w)存储到r3指向的位置。此时r3包含0x20009c48,r2包含0x00000061。然而,与以前不同的是,这会破坏lfn,将0x2000061放入其中。这显然影响着lfn本身

在这段代码的整个执行过程中,堆栈指针本身不会改变

我想知道dj->lfn中的lfn是指向uint16_t的指针,而不是大小有限的数组,这是否是一个突出的问题?dj是DIR类型的结构,定义如下:

typedef struct {
    FATFS*  fs;             /* Pointer to the owner file system object */
    WORD    id;             /* Owner file system mount ID */
    WORD    index;          /* Current read/write index number */
    DWORD   sclust;         /* Table start cluster (0:Root dir) */
    DWORD   clust;          /* Current cluster */
    DWORD   sect;           /* Current sector */
    BYTE*   dir;            /* Pointer to the current SFN entry in the win[] */
    BYTE*   fn;             /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
    WCHAR*  lfn;            /* Pointer to the LFN working buffer */
    WORD    lfn_idx;        /* Last matched LFN index number (0xFFFF:No LFN) */
} DIR;

WCHAR等于一个无符号的16位值

tp是如何定义的,以及它在本代码开头指向何处;TCHAR等于uint16\u t*tp=fno->lfname;这是在最初的帖子中:好的——它在代码的开头指向哪里——看起来它可能只是一个未初始化的指针,然后再去引用它?也许那一行是错误的,应该是:tp=fno->lfname?我不太清楚你的意思。你是在问tp设置为什么或fno->lfname吗?好的-tp是一个指针-它在你给我们看的代码中没有初始化,但是你在*tp=fno->lfname处取消引用它;这很可能是个问题。我猜这行应该是:tp=fno->lfname;你在编译时没有启用警告,所以没有被注意到?