【问题标题】:realloc overwrite variable (Xilinx SDK on a Zynq SoC (Cortex A9))realloc 覆盖变量(Zynq SoC (Cortex A9) 上的 Xilinx SDK)
【发布时间】:2016-06-08 07:58:45
【问题描述】:

如前所述,我有一个 Zynq SoC(ZC706 评估板),我正在尝试从 SD 卡读取图像。为此,我正在使用 FatFs 库 (http://elm-chan.org/fsw/ff/00index_e.html)。 在我的代码中,我从文件中读取了 4096 字节并将其保存到缓冲区中。之后,我将缓冲区复制到一个 unsigned char 指针,该指针在每次读取操作后都会增加该大小。

然后我使用 realloc,copyU32ArrayToUnsignedCharArray 函数中的 for 循环“失败”,因为 size 变量被 out 数组覆盖。

覆盖copyU32ArrayToUnsignedCharArray函数中“大小”的代码:

u32 buffer[1024];
unsigned char *img = NULL;
bytesreaded = 0;
for (;;) {
    br=0;
    fr = f_read(&fil, buffer, sizeof(buffer), &br); /* Read a chunk of source file */
    if (fr || br == 0)
        break; /* error or eof */

    img = realloc(img,br);
    copyU32ArrayToUnsignedCharArray(buffer, &img[bytesreaded], br/4); // /4 because u32(32 bit) in to unsigned char(8 bit)
    bytesreaded += br; // update readed bytes 
}

有效的代码:

    u32 buffer[1024];
unsigned char *img = NULL;
img = malloc(512*512*3+100);
bytesreaded = 0;
for (;;) {
    br=0;
    fr = f_read(&fil, buffer, sizeof(buffer), &br); /* Read a chunk of source file */
    if (fr || br == 0)
        break; /* error or eof */

    copyU32ArrayToUnsignedCharArray(buffer, &img[bytesreaded], br/4); // /4 because u32(32 bit) in to unsigned char(8 bit)
    bytesreaded += br; // update readed bytes 
}

copyU32ArrayToUnsignedCharArray 函数:

void copyU32ArrayToUnsignedCharArray(u32 *in, unsigned char* out, uint size){
int i,x;

x = 0;
for (i = 0; i < size; i++) {
    if(size != 1024)
        break;
    in[i] = Xil_In32BE(&in[i]);
    out[x] = (u32) in[i] >> 24;
    out[x + 1] = (u32) in[i] >> 16 & 0x00FF;
    out[x + 2] = (u32) in[i] >> 8 & 0x0000FF;
    out[x + 3] = (u32) in[i] & 0x000000FF;
    x += 4;
}
}

我想使用 realloc,因为我不知道我读取的图像会有多大。

更新:
一些无效的代码的进一步信息。我对其进行了调试,指向 *img 的指针不为空,因此 realloc 成功。如果我使用 gdb,copyU32ArrayToUnsignedCharArray 函数中会发生以下情况:
- 指向变量“out”的指针是 0x001125a8
- “size”变量的地址是0x0011309c(这个位置存储的值是正确的)
- 这两个变量之间的内存空间是 0xaf4 = 2804 dec(两个地址的差异)
- 如果 copyU32ArrayToUnsignedCharArray 函数中的 for 循环达到 i=702 和 x=2808,则将大小变量更改为另一个值

此致
阿诺

【问题讨论】:

  • "...'failed' 因为 size 变量被 out 数组覆盖了。" - 你怎么看出来的? size 是函数参数,其地址永远不会被占用,因此甚至不一定有可以被覆盖的存储空间(实际上,that function can easily do its thing entirely in registers)。另外,鉴于您没有检查返回值,您怎么知道realloc() 本身不会失败(或者鉴于这似乎是一个裸机环境,不只是简单地实现为return NULL;) ?
  • 我忘了提到该应用程序是裸机的。我用gdb调试了程序,看看内存。指针的地址是 0x1125a8,大小的地址是 0x11309c。所以这与0xaf4之间有一个空格。大小变量被覆盖,然后变量 i 是 701 和 x 2804。如果我将十进制数 2804 转换为十六进制,我会得到我之前计算的差异 (2804 = 0xaf4)
  • 您的评论完全不清楚....您能详细说明一下吗?你是说size的参数地址在copyU32ArrayToUnsignedCharArray执行的某个点被覆盖了?.....
  • 顺便说一句,@Notlikethat 给您写的内容是重点:您必须检查realloc 返回值以确保realloc 成功分配了所需的内存。
  • 嗯,这反而表明由于某种原因您的堆栈和堆太靠近并且相互碰撞,在这种情况下,问题与任何这段代码无关(我猜想重复的 realloc() 调用可能会搅动堆以使其恶化)。

标签: c arm realloc xilinx


【解决方案1】:

我用 Notlikethat 的提示解决了这个问题。问题是小堆大小。通过编辑链接描述文件来增加堆

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    相关资源
    最近更新 更多