【问题标题】:Dynamically expanding array using realloc使用 realloc 动态扩展数组
【发布时间】:2013-02-11 23:45:00
【问题描述】:

我编写了以下代码来清楚地了解 malloc 和 realloc。 我已经使用 malloc 初始化指针,然后使用 realloc,我正在增加数组的大小。 但是当我运行代码时出现以下错误。

#include<stdio.h>
#include<stdlib.h>

int main()
{
    char *p;
    p = malloc(10);
    p = " this is it";
    printf("\n%s", p);
    p = realloc(p, 14);
    p[11] = 'A';
    p[12] = 'B';
    p[13] = 'C';
    printf("\n %s", p) ;
    return 0;
}

输出:

ajay@ajay-K54L:~$ gcc te.c 
ajay@ajay-K54L:~$ ./a.out

*** glibc detected *** ./a.out: realloc(): invalid pointer: 0x000000000040071c ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7e626)[0x7fb111e88626]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x2de)[0x7fb111e8d3ee]
./a.out[0x4005dc]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fb111e2b76d]
./a.out[0x4004d9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:03 3027043                            /home/ajay/a.out
00600000-00601000 r--p 00000000 08:03 3027043                            /home/ajay/a.out
00601000-00602000 rw-p 00001000 08:03 3027043                            /home/ajay/a.out
00e76000-00e97000 rw-p 00000000 00:00 0                                  [heap]
7fb111bf4000-7fb111c09000 r-xp 00000000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111c09000-7fb111e08000 ---p 00015000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111e08000-7fb111e09000 r--p 00014000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111e09000-7fb111e0a000 rw-p 00015000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111e0a000-7fb111fbd000 r-xp 00000000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb111fbd000-7fb1121bc000 ---p 001b3000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb1121bc000-7fb1121c0000 r--p 001b2000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb1121c0000-7fb1121c2000 rw-p 001b6000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb1121c2000-7fb1121c7000 rw-p 00000000 00:00 0 
7fb1121c7000-7fb1121e9000 r-xp 00000000 08:03 2100760                    /lib/x86_64-linux-gnu/ld-2.15.so
7fb1123d2000-7fb1123d5000 rw-p 00000000 00:00 0 
7fb1123e5000-7fb1123e9000 rw-p 00000000 00:00 0 
7fb1123e9000-7fb1123ea000 r--p 00022000 08:03 2100760                    /lib/x86_64-linux-gnu/ld-2.15.so
7fb1123ea000-7fb1123ec000 rw-p 00023000 08:03 2100760                    /lib/x86_64-linux-gnu/ld-2.15.so
7ffff08d4000-7ffff08f5000 rw-p 00000000 00:00 0                          [stack]
7ffff09ff000-7ffff0a00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
 this is itAborted (core dumped)

我在内存分配方面做错了什么? 谢谢。

【问题讨论】:

标签: c pointers malloc realloc


【解决方案1】:
char *p = malloc(10);

分配大小为10 的内存块并使p 指向该内存。那么

p = " this is it";

定义一个常量字符串文字并使p 指向只读内存,该常量字符串文字存储在其中。所以

p = realloc(p, 14);

尝试realloc这个产生未定义行为的只读内存。


不要将常量字符串文字的地址分配给p(这也会产生内存泄漏,因为您动态分配的内存地址丢失了),您应该复制此字符串通过使用strcpy。所以替换这一行:

p = " this is it";

用这个:

strcpy(p, " this is it");

【讨论】:

    【解决方案2】:

    这个:

    p = " this is it"; /* Does not copy, use strcpy(). */
    

    将字符串文字的地址分配给p,从malloc() 之前返回的地址更改它。传递给realloc() 的指针必须是:

    ...以前由 malloc()、calloc() 或 realloc() 分配,但尚未用 free() 释放,否则,结果未定义。

    例如将分配更改为strcpy() 以更正:

    p = malloc(12); /* Increased size. */
    if (p)
    {
        strcpy(p, " this is it");
        char* tmp = realloc(p, 14);  /* Store result in temp to avoid potential */
        if (!tmp)                    /* in the event that realloc() fails. */
        {
            free(p);
            return -1;
        }
        p = tmp;
        /* snip ... */
    
        free(p); /* When 'p' is no longer required. */
    }
    

    【讨论】:

    • 此外,“就是这样”需要存储 12 个字节,因此即使 strcpy 也无法按预期工作,因为只分配了 10 个字节。使用strncpy(并确保分配足够的内存)
    • 阿杰,取决于你在做什么,但realloc is probably not the answer。如果它被分隔,您可以在某些平台上使用 getdelim / getline 或在其他平台上使用其他变体。通常,预先分配一定大小的缓冲区就足够了。
    【解决方案3】:

    您正在用字符串覆盖malloc() 返回的指针:

    p = " this is it";
    

    你应该使用strcpy()将字符串复制到p指向的内存中:

    strcpy(p, "this is it");
    

    但请注意,上述字符串需要的空间比您分配的要多:它是 10 个可见字符,但字符串有一个 0 字符作为终止符,因此您至少需要 11 个字符的空间。

    此外,您应该在依赖指针有效之前检查malloc()realloc() 的返回值。如果是NULL,则分配失败。这不太可能考虑到您的分配大小,但这是一种很好的做法。

    【讨论】:

      猜你喜欢
      • 2013-06-11
      • 2016-04-09
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 2013-03-31
      相关资源
      最近更新 更多